From e02e7f1eae575441f7453a8c0d1860fc3582d1a4 Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Thu, 16 Nov 2023 00:05:11 +0530 Subject: [PATCH 01/40] added more tests; realigned the jest config --- packages/client/jest.config.js | 2 +- packages/client/package.json | 2 +- packages/client/src/__mocks__/clientMocks.ts | 25 +++++++++++ packages/client/src/__mocks__/fixtures.ts | 7 ++++ packages/client/src/ipfs/index.ts | 4 +- .../src/profile/__tests__/profile.spec.ts | 41 +++++++++++++++++++ packages/client/src/viem/index.ts | 3 +- 7 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 packages/client/src/__mocks__/clientMocks.ts create mode 100644 packages/client/src/__mocks__/fixtures.ts create mode 100644 packages/client/src/profile/__tests__/profile.spec.ts diff --git a/packages/client/jest.config.js b/packages/client/jest.config.js index 55b7821..fd7306b 100644 --- a/packages/client/jest.config.js +++ b/packages/client/jest.config.js @@ -4,7 +4,7 @@ module.exports = { testEnvironment: 'node', rootDir: './', coverageDirectory: '/coverage', - collectCoverageFrom: ['/packages/client/src/**/*.ts'], + collectCoverageFrom: ['/src/**/*.ts'], testPathIgnorePatterns: ['/node_modules'], coverageReporters: ['json', 'lcov', 'html'] }; \ No newline at end of file diff --git a/packages/client/package.json b/packages/client/package.json index 99a2446..852880f 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -12,7 +12,7 @@ "prepare": "npm run build", "build": "tsup src/index.ts --format cjs,esm --dts", "dev": "npm run build -- --watch", - "test": "jest --coverage" + "test": "jest --verbose --coverage" }, "devDependencies": { "@turbo/gen": "^1.10.12", diff --git a/packages/client/src/__mocks__/clientMocks.ts b/packages/client/src/__mocks__/clientMocks.ts new file mode 100644 index 0000000..86dbdad --- /dev/null +++ b/packages/client/src/__mocks__/clientMocks.ts @@ -0,0 +1,25 @@ +import { getProfileByAddress } from "../profile/graphql"; +import { mockGraphQlUsersResponse, testAddress, testIpfsHash } from "./fixtures"; + +export class MockGraphQLClient { + async get(query: string) { + if (query === getProfileByAddress(testAddress)) { + return mockGraphQlUsersResponse; + } + // Mock response based on the query + return { data: { "racoon": "bar" } }; + } +} + +export class MockViemClient { + // Add methods that are used in the Profile class + async writeContract(/* parameters */) { + // Mock response for writeContract + return testAddress; + } +} + +export class MockIPFSClient { + post = jest.fn().mockResolvedValue(testIpfsHash); + +} \ No newline at end of file diff --git a/packages/client/src/__mocks__/fixtures.ts b/packages/client/src/__mocks__/fixtures.ts new file mode 100644 index 0000000..56e90a8 --- /dev/null +++ b/packages/client/src/__mocks__/fixtures.ts @@ -0,0 +1,7 @@ +export const testAddress = "0xRacoon"; +export const testName = 'racoon'; +export const testAbout = 'a helpful racoon here to help with tests'; +export const testPlatformId = 1; +export const mockGraphQlUsersResponse = { data: { users: [{ name: testName }] } }; +export const testIpfsHash = 'ipfsHash'; +export const testProfileData = { name: testName, about: testAbout }; \ No newline at end of file diff --git a/packages/client/src/ipfs/index.ts b/packages/client/src/ipfs/index.ts index 490505b..7382b45 100644 --- a/packages/client/src/ipfs/index.ts +++ b/packages/client/src/ipfs/index.ts @@ -10,6 +10,8 @@ export default class IPFSClient { const authorization = 'Basic ' + btoa(ipfsClientConfig.clientId + ':' + ipfsClientConfig.clientSecret); this.authorization = authorization; + // ipfs-http-client is being mocked by src/__mocks__/ipfs-http-client + // due to the way its being imported in ipfs/index.ts, we have to add a special mock for it import('ipfs-http-client').then(({ create }) => { this.ipfs = create({ url: ipfsClientConfig.baseUrl, @@ -20,7 +22,7 @@ export default class IPFSClient { }); } - public async post(data: string): Promise { + public async post(data: string): Promise { const formData = new FormData(); formData.append('file', new Blob([data], { type: 'application/json' })); diff --git a/packages/client/src/profile/__tests__/profile.spec.ts b/packages/client/src/profile/__tests__/profile.spec.ts new file mode 100644 index 0000000..18b6c68 --- /dev/null +++ b/packages/client/src/profile/__tests__/profile.spec.ts @@ -0,0 +1,41 @@ +import { Profile } from ".."; +import { MockGraphQLClient, MockIPFSClient, MockViemClient } from "../../__mocks__/clientMocks"; +import { testAddress, testIpfsHash, testName, testPlatformId, testProfileData } from "../../__mocks__/fixtures"; + +describe('Profile', () => { + let mockGraphQLClient: any; + let mockViemClient: any; + let mockIPFSClient: any; + let profile: Profile; + + beforeEach(() => { + mockGraphQLClient = new MockGraphQLClient(); + mockViemClient = new MockViemClient(); + mockIPFSClient = new MockIPFSClient(); + profile = new Profile(mockGraphQLClient, mockIPFSClient, mockViemClient, testPlatformId); + }); + + it('constructor initializes correctly', () => { + expect(profile).toBeInstanceOf(Profile); + }); + + describe('getByAddress', () => { + it('getByAddress returns data for a given address', async () => { + + const address = testAddress; + const result = await profile.getByAddress(address); + expect(result.name).toEqual(testName); + }); + }); + + describe('upload', () => { + it('should upload profile data and return a string', async () => { + const result = await profile.upload(testProfileData); + expect(mockIPFSClient.post).toHaveBeenCalledWith(JSON.stringify(testProfileData)); + + expect(result).toBe(testIpfsHash); + }); + }); + + +}); diff --git a/packages/client/src/viem/index.ts b/packages/client/src/viem/index.ts index a0367de..efa2769 100644 --- a/packages/client/src/viem/index.ts +++ b/packages/client/src/viem/index.ts @@ -5,6 +5,7 @@ import { http, WalletClient, PublicClient, + Hash, } from 'viem'; import { mnemonicToAccount, privateKeyToAccount } from 'viem/accounts'; import { getChainConfig } from '../config'; @@ -80,7 +81,7 @@ export class ViemClient { functionName: string, args: Array, value?: bigint, - ) { + ): Promise { // @ts-ignore const [address] = await this.client.getAddresses(); From 5a11118dab06ba33a19de877960792d1283df639 Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Thu, 16 Nov 2023 22:05:59 +0530 Subject: [PATCH 02/40] increased coverage for profile/index.ts --- packages/client/src/__mocks__/clientMocks.ts | 28 +++++++++++++------ packages/client/src/__mocks__/fixtures.ts | 26 +++++++++++++++++ .../src/profile/__tests__/profile.spec.ts | 26 ++++++++++++++++- packages/client/src/profile/graphql/index.ts | 9 ++++++ packages/client/src/profile/index.ts | 13 ++------- 5 files changed, 82 insertions(+), 20 deletions(-) diff --git a/packages/client/src/__mocks__/clientMocks.ts b/packages/client/src/__mocks__/clientMocks.ts index 86dbdad..7f5a9d1 100644 --- a/packages/client/src/__mocks__/clientMocks.ts +++ b/packages/client/src/__mocks__/clientMocks.ts @@ -1,22 +1,32 @@ -import { getProfileByAddress } from "../profile/graphql"; -import { mockGraphQlUsersResponse, testAddress, testIpfsHash } from "./fixtures"; +import { getProtocolById } from "../platform/graphql/queries"; +import { getMintFees, getProfileByAddress } from "../profile/graphql"; +import { mockGraphQlMintFeesResponse, mockGraphQlProtocolByIdResponse, mockGraphQlUsersResponse, testAddress, testIpfsHash } from "./fixtures"; export class MockGraphQLClient { - async get(query: string) { + get = jest.fn(async (query: string) => { if (query === getProfileByAddress(testAddress)) { return mockGraphQlUsersResponse; } - // Mock response based on the query + + if (query === getMintFees()) { + return mockGraphQlMintFeesResponse + } + + if (query === getProtocolById(1)) { + return mockGraphQlProtocolByIdResponse; + } + return { data: { "racoon": "bar" } }; - } + }) + } export class MockViemClient { - // Add methods that are used in the Profile class - async writeContract(/* parameters */) { - // Mock response for writeContract + writeContract = jest.fn(async (...args) => { + console.log("args:", args) return testAddress; - } + }) + } export class MockIPFSClient { diff --git a/packages/client/src/__mocks__/fixtures.ts b/packages/client/src/__mocks__/fixtures.ts index 56e90a8..eea1ab8 100644 --- a/packages/client/src/__mocks__/fixtures.ts +++ b/packages/client/src/__mocks__/fixtures.ts @@ -3,5 +3,31 @@ export const testName = 'racoon'; export const testAbout = 'a helpful racoon here to help with tests'; export const testPlatformId = 1; export const mockGraphQlUsersResponse = { data: { users: [{ name: testName }] } }; +export const mockGraphQlMintFeesResponse = { + data: { + protocols: [ + { + userMintFee: '1000000000000000000', + shortHandlesMaxPrice: '200000000000000000000' + } + ] + } +} + + +export const mockGraphQlProtocolByIdResponse = { + data: { + protocol: { + id: '1', + userMintFee: '1000000000000000000', + platformMintFee: '0', + protocolEscrowFeeRate: 100, + totalMintFees: '12929000000000000000000', + minArbitrationFeeTimeout: '864000', + shortHandlesMaxPrice: '200000000000000000000', + minServiceCompletionPercentage: '30' + } + } +} export const testIpfsHash = 'ipfsHash'; export const testProfileData = { name: testName, about: testAbout }; \ No newline at end of file diff --git a/packages/client/src/profile/__tests__/profile.spec.ts b/packages/client/src/profile/__tests__/profile.spec.ts index 18b6c68..9d0b373 100644 --- a/packages/client/src/profile/__tests__/profile.spec.ts +++ b/packages/client/src/profile/__tests__/profile.spec.ts @@ -1,6 +1,11 @@ import { Profile } from ".."; +// DO NOT remove this comments - they are needed for local testing +// import { getGraphQLConfig } from "../../config"; +// import GraphQLClient from "../../graphql"; +import { getProtocolById } from "../../platform/graphql/queries"; import { MockGraphQLClient, MockIPFSClient, MockViemClient } from "../../__mocks__/clientMocks"; -import { testAddress, testIpfsHash, testName, testPlatformId, testProfileData } from "../../__mocks__/fixtures"; +import { mockGraphQlMintFeesResponse, testAddress, testIpfsHash, testName, testPlatformId, testProfileData } from "../../__mocks__/fixtures"; +import { getMintFees } from "../graphql"; describe('Profile', () => { let mockGraphQLClient: any; @@ -10,6 +15,8 @@ describe('Profile', () => { beforeEach(() => { mockGraphQLClient = new MockGraphQLClient(); + // DO NOT remove this comments - they are needed for local testing + // mockGraphQLClient = new GraphQLClient(getGraphQLConfig(137)) mockViemClient = new MockViemClient(); mockIPFSClient = new MockIPFSClient(); profile = new Profile(mockGraphQLClient, mockIPFSClient, mockViemClient, testPlatformId); @@ -19,6 +26,15 @@ describe('Profile', () => { expect(profile).toBeInstanceOf(Profile); }); + describe('create', () => { + it('should create a new profile and return a response', async () => { + const handle = testName; + const result = await profile.create(handle); + expect(mockGraphQLClient.get).toHaveBeenCalledWith(getProtocolById(1)); + expect(mockViemClient.writeContract).toHaveBeenCalledWith('talentLayerId', 'mint', ['1', 'racoon'], BigInt("1000000000000000000")) + }) + }) + describe('getByAddress', () => { it('getByAddress returns data for a given address', async () => { @@ -37,5 +53,13 @@ describe('Profile', () => { }); }); + describe('getMintFees', () => { + it('should return mint fees', async () => { + const result = await profile.getMintFees(); + expect(mockGraphQLClient.get).toHaveBeenCalledWith(getMintFees()); + expect(result).toEqual(mockGraphQlMintFeesResponse.data); + }); + }); + }); diff --git a/packages/client/src/profile/graphql/index.ts b/packages/client/src/profile/graphql/index.ts index 93b889e..e7b1b79 100644 --- a/packages/client/src/profile/graphql/index.ts +++ b/packages/client/src/profile/graphql/index.ts @@ -148,3 +148,12 @@ export const getPaymentsForUser = ( `; return query; }; + +export const getMintFees = () => ` +{ + protocols { + userMintFee, + shortHandlesMaxPrice + } +} +`; \ No newline at end of file diff --git a/packages/client/src/profile/index.ts b/packages/client/src/profile/index.ts index 17094f5..672af93 100644 --- a/packages/client/src/profile/index.ts +++ b/packages/client/src/profile/index.ts @@ -4,7 +4,7 @@ import IPFSClient from '../ipfs'; import { getProtocolById } from '../platform/graphql/queries'; import { ClientTransactionResponse } from '../types'; import { ViemClient } from '../viem'; -import { getPaymentsForUser, getProfileByAddress, getProfileById, getProfiles, getUserTotalGains } from './graphql'; +import { getMintFees, getPaymentsForUser, getProfileByAddress, getProfileById, getProfiles, getUserTotalGains } from './graphql'; import { TalentLayerProfile } from './types'; export class Profile { @@ -37,7 +37,7 @@ export class Profile { return null; } - + public async getById(userId: string): Promise { const query = getProfileById(userId); @@ -126,14 +126,7 @@ export class Profile { } public async getMintFees(): Promise { - const query = ` - { - protocols { - userMintFee, - shortHandlesMaxPrice - } - } - `; + const query = getMintFees(); const response = await this.graphQlClient.get(query); From 8dcfe21f175b2bfa60fda285fb943154a4dc7be0 Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Fri, 17 Nov 2023 22:56:48 +0530 Subject: [PATCH 03/40] added tests for all functions in profile class --- packages/client/src/__mocks__/clientMocks.ts | 20 ++++++- packages/client/src/__mocks__/fixtures.ts | 34 +++++++++++- .../src/profile/__tests__/profile.spec.ts | 53 ++++++++++++++++++- 3 files changed, 102 insertions(+), 5 deletions(-) diff --git a/packages/client/src/__mocks__/clientMocks.ts b/packages/client/src/__mocks__/clientMocks.ts index 7f5a9d1..bc76e30 100644 --- a/packages/client/src/__mocks__/clientMocks.ts +++ b/packages/client/src/__mocks__/clientMocks.ts @@ -1,6 +1,6 @@ import { getProtocolById } from "../platform/graphql/queries"; -import { getMintFees, getProfileByAddress } from "../profile/graphql"; -import { mockGraphQlMintFeesResponse, mockGraphQlProtocolByIdResponse, mockGraphQlUsersResponse, testAddress, testIpfsHash } from "./fixtures"; +import { getMintFees, getPaymentsForUser, getProfileByAddress, getProfileById, getProfiles, getUserTotalGains } from "../profile/graphql"; +import { mockGraphQlMintFeesResponse, mockGraphQlProtocolByIdResponse, mockGraphQlUsersResponse, testAddress, testGetProfilesResponse, testIpfsHash, testUserId, testUserPaymentsResponse, testUserResponse, testUserTotalGainsResponse } from "./fixtures"; export class MockGraphQLClient { get = jest.fn(async (query: string) => { @@ -16,6 +16,22 @@ export class MockGraphQLClient { return mockGraphQlProtocolByIdResponse; } + if (query === getProfileById(testUserId)) { + return testUserResponse; + } + + if (query === getProfiles(1, 0, 'racoon')) { + return testGetProfilesResponse; + } + + if (query === getPaymentsForUser(testUserId)) { + return testUserPaymentsResponse; + } + + if (query === getUserTotalGains(testUserId)) { + return testUserTotalGainsResponse; + } + return { data: { "racoon": "bar" } }; }) diff --git a/packages/client/src/__mocks__/fixtures.ts b/packages/client/src/__mocks__/fixtures.ts index eea1ab8..dad3339 100644 --- a/packages/client/src/__mocks__/fixtures.ts +++ b/packages/client/src/__mocks__/fixtures.ts @@ -1,5 +1,34 @@ export const testAddress = "0xRacoon"; export const testName = 'racoon'; +export const testUserId = '2371'; +export const testUserResponse = { + data: { + user: { + id: '1', + address: '0x870b08a222f8eac75b6bf85988df7597c0ae20a9', + handle: 'talentlayer', + rating: '0', + delegates: [], + userStats: { numReceivedReviews: '0' }, + updatedAt: '1680621215', + createdAt: '1680608213', + description: { + about: 'TalentLayer is composable, decentralized, open-source infrastructure for talent markets; allowing anyone to easily build interoperable gig marketplaces.', + role: 'buyer', + name: 'TalentLayer', + country: null, + headline: null, + id: 'QmeTSoJnRNZ6WNeVa5mQ2rkdfALjy4EdyLgTyYyq2AWDAn-1680621215', + image_url: null, + video_url: null, + title: 'Future of work builder', + timezone: null, + skills_raw: 'solidity,blockchain', + web3mailPreferences: null + } + } + } +} export const testAbout = 'a helpful racoon here to help with tests'; export const testPlatformId = 1; export const mockGraphQlUsersResponse = { data: { users: [{ name: testName }] } }; @@ -30,4 +59,7 @@ export const mockGraphQlProtocolByIdResponse = { } } export const testIpfsHash = 'ipfsHash'; -export const testProfileData = { name: testName, about: testAbout }; \ No newline at end of file +export const testProfileData = { name: testName, about: testAbout }; +export const testGetProfilesResponse = { "data": { "users": [{ "id": "11962", "address": "0x02289d0ebf8836e6f98af170b88b9f8eb889e2c6", "handle": "racoon", "userStats": { "numReceivedReviews": "0" }, "rating": "0" }] } } +export const testUserTotalGainsResponse = { data: { user: { totalGains: [{ "id": "2371-0x2791bca1f2de4661ed88a30c99a7a9449aa84174", "totalGain": "850000000", "token": { "id": "0xracoon", "name": "USD Coin (PoS)", "symbol": "USDC", "decimals": "6" } }] } } } +export const testUserPaymentsResponse = { data: { payments: [{ "id": "0x3eb5973863d712ce78dc757af04ca24a81d0376dbce604d002779475428e4a85-975", "rateToken": { "address": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174", "decimals": "6", "name": "USD Coin (PoS)", "symbol": "USDC" }, "amount": "850000000", "transactionHash": "0x3eb5973863d712ce78dc757af04ca24a81d0376dbce604d002779475428e4a85", "paymentType": "Release", "createdAt": "1699361940", "service": { "id": "75", "cid": "abcd" } }] } } \ No newline at end of file diff --git a/packages/client/src/profile/__tests__/profile.spec.ts b/packages/client/src/profile/__tests__/profile.spec.ts index 9d0b373..81ea9c9 100644 --- a/packages/client/src/profile/__tests__/profile.spec.ts +++ b/packages/client/src/profile/__tests__/profile.spec.ts @@ -4,8 +4,8 @@ import { Profile } from ".."; // import GraphQLClient from "../../graphql"; import { getProtocolById } from "../../platform/graphql/queries"; import { MockGraphQLClient, MockIPFSClient, MockViemClient } from "../../__mocks__/clientMocks"; -import { mockGraphQlMintFeesResponse, testAddress, testIpfsHash, testName, testPlatformId, testProfileData } from "../../__mocks__/fixtures"; -import { getMintFees } from "../graphql"; +import { mockGraphQlMintFeesResponse, testAddress, testGetProfilesResponse, testIpfsHash, testName, testPlatformId, testProfileData, testUserId, testUserPaymentsResponse, testUserResponse, testUserTotalGainsResponse } from "../../__mocks__/fixtures"; +import { getMintFees, getProfileById, getProfiles } from "../graphql"; describe('Profile', () => { let mockGraphQLClient: any; @@ -26,6 +26,29 @@ describe('Profile', () => { expect(profile).toBeInstanceOf(Profile); }); + describe('getById', () => { + it('should return user based on input it', async () => { + const userId = testUserId; + const result = await profile.getById(userId); + expect(result).toEqual(testUserResponse.data.user); + expect(mockGraphQLClient.get).toHaveBeenCalledWith(getProfileById(userId)); + + }) + }) + + describe('update', () => { + it('should successfully update profile hash and update on contract', async () => { + const profileData = testProfileData; + const updateResponse = await profile.update(profileData, testUserId); + expect(updateResponse.cid).toEqual(testIpfsHash); + expect(updateResponse.tx).toEqual(testAddress); + expect(mockViemClient.writeContract).toHaveBeenCalledWith('talentLayerId', 'updateProfileData', [ + testUserId, + testIpfsHash + ]) + }) + }) + describe('create', () => { it('should create a new profile and return a response', async () => { const handle = testName; @@ -61,5 +84,31 @@ describe('Profile', () => { }); }); + describe('getBy', () => { + it('should return profiles based on provided parameters', async () => { + const params = { numberPerPage: 1, offset: 0, searchQuery: 'racoon' }; + + const result = await profile.getBy(params); + expect(mockGraphQLClient.get).toHaveBeenCalledWith(getProfiles(params.numberPerPage, params.offset, params.searchQuery)); + expect(result).toEqual(testGetProfilesResponse); + }); + }); + + describe('getTotalGains', () => { + it('should return the total gains for a user', async () => { + const userId = testUserId; + const result = await profile.getTotalGains(userId); + expect(result).toEqual(testUserTotalGainsResponse.data.user.totalGains); + }); + }); + + describe('getPayments', () => { + it('should return payment data for a user', async () => { + const userId = testUserId; + const result = await profile.getPayments(userId); + expect(result).toEqual(testUserPaymentsResponse.data.payments); + }); + }); + }); From 8c9ce199cde6106c15978eebf64c5025cefd69f5 Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Sat, 18 Nov 2023 01:44:32 +0530 Subject: [PATCH 04/40] added tests for disputes class --- packages/client/src/__mocks__/clientMocks.ts | 22 +++-- packages/client/src/__mocks__/fixtures.ts | 7 +- .../src/disputes/__tests__/disputes.spec.ts | 82 +++++++++++++++++++ packages/client/src/disputes/index.ts | 4 +- 4 files changed, 104 insertions(+), 11 deletions(-) create mode 100644 packages/client/src/disputes/__tests__/disputes.spec.ts diff --git a/packages/client/src/__mocks__/clientMocks.ts b/packages/client/src/__mocks__/clientMocks.ts index bc76e30..b16ad2b 100644 --- a/packages/client/src/__mocks__/clientMocks.ts +++ b/packages/client/src/__mocks__/clientMocks.ts @@ -1,6 +1,6 @@ -import { getProtocolById } from "../platform/graphql/queries"; +import { getPlatformById, getProtocolById } from "../platform/graphql/queries"; import { getMintFees, getPaymentsForUser, getProfileByAddress, getProfileById, getProfiles, getUserTotalGains } from "../profile/graphql"; -import { mockGraphQlMintFeesResponse, mockGraphQlProtocolByIdResponse, mockGraphQlUsersResponse, testAddress, testGetProfilesResponse, testIpfsHash, testUserId, testUserPaymentsResponse, testUserResponse, testUserTotalGainsResponse } from "./fixtures"; +import { mockGraphQlMintFeesResponse, mockGraphQlProtocolByIdResponse, mockGraphQlUsersResponse, testAddress, testGetProfilesResponse, testIpfsHash, testPlatformId, testPlatformResponse, testPlatformResponseWithArbitrator, testUserId, testUserPaymentsResponse, testUserResponse, testUserTotalGainsResponse } from "./fixtures"; export class MockGraphQLClient { get = jest.fn(async (query: string) => { @@ -32,20 +32,28 @@ export class MockGraphQLClient { return testUserTotalGainsResponse; } + if (query === getPlatformById(testPlatformId.toString())) { + return testPlatformResponse; + } + + if (query === getPlatformById("2")) { + return testPlatformResponseWithArbitrator; + } + return { data: { "racoon": "bar" } }; }) } export class MockViemClient { - writeContract = jest.fn(async (...args) => { - console.log("args:", args) - return testAddress; - }) + writeContract = jest.fn(async () => testAddress) + readContract = jest.fn(async () => "randomData") + publicClient = { + readContract: jest.fn(async () => "randomData") + } } export class MockIPFSClient { post = jest.fn().mockResolvedValue(testIpfsHash); - } \ No newline at end of file diff --git a/packages/client/src/__mocks__/fixtures.ts b/packages/client/src/__mocks__/fixtures.ts index dad3339..2fb7e89 100644 --- a/packages/client/src/__mocks__/fixtures.ts +++ b/packages/client/src/__mocks__/fixtures.ts @@ -1,6 +1,7 @@ export const testAddress = "0xRacoon"; export const testName = 'racoon'; export const testUserId = '2371'; +export const testChainId = 137; export const testUserResponse = { data: { user: { @@ -62,4 +63,8 @@ export const testIpfsHash = 'ipfsHash'; export const testProfileData = { name: testName, about: testAbout }; export const testGetProfilesResponse = { "data": { "users": [{ "id": "11962", "address": "0x02289d0ebf8836e6f98af170b88b9f8eb889e2c6", "handle": "racoon", "userStats": { "numReceivedReviews": "0" }, "rating": "0" }] } } export const testUserTotalGainsResponse = { data: { user: { totalGains: [{ "id": "2371-0x2791bca1f2de4661ed88a30c99a7a9449aa84174", "totalGain": "850000000", "token": { "id": "0xracoon", "name": "USD Coin (PoS)", "symbol": "USDC", "decimals": "6" } }] } } } -export const testUserPaymentsResponse = { data: { payments: [{ "id": "0x3eb5973863d712ce78dc757af04ca24a81d0376dbce604d002779475428e4a85-975", "rateToken": { "address": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174", "decimals": "6", "name": "USD Coin (PoS)", "symbol": "USDC" }, "amount": "850000000", "transactionHash": "0x3eb5973863d712ce78dc757af04ca24a81d0376dbce604d002779475428e4a85", "paymentType": "Release", "createdAt": "1699361940", "service": { "id": "75", "cid": "abcd" } }] } } \ No newline at end of file +export const testUserPaymentsResponse = { data: { payments: [{ "id": "0x3eb5973863d712ce78dc757af04ca24a81d0376dbce604d002779475428e4a85-975", "rateToken": { "address": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174", "decimals": "6", "name": "USD Coin (PoS)", "symbol": "USDC" }, "amount": "850000000", "transactionHash": "0x3eb5973863d712ce78dc757af04ca24a81d0376dbce604d002779475428e4a85", "paymentType": "Release", "createdAt": "1699361940", "service": { "id": "75", "cid": "abcd" } }] } } + +export const testPlatformResponse = { "data": { "platform": { "id": "1", "address": "0xracoon", "name": "abcd", "createdAt": "1681454011", "updatedAt": "1681454011", "originServiceFeeRate": 0, "originValidatedProposalFeeRate": 0, "servicePostingFee": "0", "proposalPostingFee": "0", "arbitrator": "0x0000000000000000000000000000000000000000", "arbitratorExtraData": "0x00000000", "arbitrationFeeTimeout": "864000", "cid": null, "signer": "0xraqcoon", "description": null } } } + +export const testPlatformResponseWithArbitrator = { "data": { "platform": { "id": "1", "address": "0xracoon", "name": "abcd", "createdAt": "1681454011", "updatedAt": "1681454011", "originServiceFeeRate": 0, "originValidatedProposalFeeRate": 0, "servicePostingFee": "0", "proposalPostingFee": "0", "arbitrator": "0xracoon", "arbitratorExtraData": "0x00000000", "arbitrationFeeTimeout": "864000", "cid": null, "signer": "0xraqcoon", "description": null } } } \ No newline at end of file diff --git a/packages/client/src/disputes/__tests__/disputes.spec.ts b/packages/client/src/disputes/__tests__/disputes.spec.ts new file mode 100644 index 0000000..83aef92 --- /dev/null +++ b/packages/client/src/disputes/__tests__/disputes.spec.ts @@ -0,0 +1,82 @@ +// START of disputes.spec.ts +import { parseEther, toHex } from "viem"; +import { Disputes } from ".."; +import { getChainConfig, getGraphQLConfig } from "../../config"; +import GraphQLClient from "../../graphql"; +import { getPlatformById } from "../../platform/graphql/queries"; +import { MockGraphQLClient, MockViemClient } from "../../__mocks__/clientMocks"; +import { testPlatformId, testChainId, testPlatformResponseWithArbitrator, testAddress } from "../../__mocks__/fixtures"; + + +describe('Disputes', () => { + let mockGraphQLClient: any; + let mockViemClient: any; + let disputes: Disputes; + + beforeEach(() => { + mockGraphQLClient = new MockGraphQLClient(); + // DO NOT remove this comments - they are needed for local testing + // mockGraphQLClient = new GraphQLClient(getGraphQLConfig(137)) + mockViemClient = new MockViemClient(); + disputes = new Disputes(mockViemClient, testPlatformId, mockGraphQLClient, testChainId); + }); + + it('constructor initializes correctly', () => { + expect(disputes).toBeInstanceOf(Disputes); + }); + + // Test for each method in Disputes class + describe('getArbitrationCost', () => { + it('should return 0 if the aribtrator address is set to zeroAddress', async () => { + // Arrange + const expectedCost = 0; + + // Act + const result = await disputes.getArbitrationCost(); + + // Assert + expect(result).toEqual(expectedCost); + expect(mockGraphQLClient.get).toHaveBeenCalledWith(getPlatformById(testPlatformId.toString())); + }); + + it('should read arbitration contract and return value if arbitrator address is not zero', async () => { + // Arrange + // set a new disputes instance with a different platform id + disputes = new Disputes(mockViemClient, 2, mockGraphQLClient, testChainId); + const chainConfig = getChainConfig(disputes.chainId); + const contract = chainConfig.contracts['talentLayerArbitrator']; + + //Act + await disputes.getArbitrationCost(); + + // Assert + expect(mockViemClient.publicClient.readContract).toHaveBeenCalledWith({ address: testPlatformResponseWithArbitrator.data.platform.arbitrator, abi: contract.abi, functionName: 'arbitrationCost', args: [toHex(disputes.platformID, { size: 32 })] }) + }) + + + + }); + + describe('setPrice', () => { + it.only('should set the price for arbitration', async () => { + // Arrange + const value = 5; + const expectedTxHash = testAddress; + + // Act + const result = await disputes.setPrice(value); + + // Assert + expect(result).toEqual(expectedTxHash); + // Check if writeContract is called with correct parameters + expect(mockViemClient.writeContract).toHaveBeenCalledWith( + 'talentLayerArbitrator', + 'setArbitrationPrice', + [testPlatformId, parseEther(value.toString())] + ); + }); + }); + +}); + +// END of disputes.spec.ts diff --git a/packages/client/src/disputes/index.ts b/packages/client/src/disputes/index.ts index a780b02..8e75e4f 100644 --- a/packages/client/src/disputes/index.ts +++ b/packages/client/src/disputes/index.ts @@ -1,4 +1,4 @@ -import { numberToBytes, numberToHex, parseEther, toBytes, toHex, zeroAddress } from 'viem'; +import { parseEther, toHex, zeroAddress } from 'viem'; import { getChainConfig } from '../config'; import GraphQLClient from '../graphql'; import { getPlatformById } from '../platform/graphql/queries'; @@ -36,7 +36,6 @@ export class Disputes { return 0; } - // Start const chainConfig = getChainConfig(this.chainId); const contract = chainConfig.contracts['talentLayerArbitrator']; @@ -45,7 +44,6 @@ export class Disputes { throw Error('Invalid contract name passed.'); } - // @ts-ignore return this.wallet.publicClient.readContract({ address: arbitrator, abi: contract.abi, From c21d807186b21a54f837af5d2b1b002074867e28 Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Sat, 18 Nov 2023 01:48:26 +0530 Subject: [PATCH 05/40] removed extra comments and only --- packages/client/src/disputes/__tests__/disputes.spec.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/client/src/disputes/__tests__/disputes.spec.ts b/packages/client/src/disputes/__tests__/disputes.spec.ts index 83aef92..c1dc293 100644 --- a/packages/client/src/disputes/__tests__/disputes.spec.ts +++ b/packages/client/src/disputes/__tests__/disputes.spec.ts @@ -1,4 +1,3 @@ -// START of disputes.spec.ts import { parseEther, toHex } from "viem"; import { Disputes } from ".."; import { getChainConfig, getGraphQLConfig } from "../../config"; @@ -58,7 +57,7 @@ describe('Disputes', () => { }); describe('setPrice', () => { - it.only('should set the price for arbitration', async () => { + it('should set the price for arbitration', async () => { // Arrange const value = 5; const expectedTxHash = testAddress; @@ -79,4 +78,3 @@ describe('Disputes', () => { }); -// END of disputes.spec.ts From 1f6d5c164fb174325f25b15415ef28c4e007da04 Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Sat, 18 Nov 2023 01:52:17 +0530 Subject: [PATCH 06/40] added ci.yml --- .github/workflows/ci.yml | 31 +++++++++++++++++++++++++++++++ package.json | 3 ++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..273f6d6 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,31 @@ +name: CI + +on: + push: + branches: ["develop"] + pull_request: + types: [opened, synchronize] + +jobs: + build: + name: Unit Tests + timeout-minutes: 15 + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v3 + with: + fetch-depth: 2 + + - name: Setup Node.js environment + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: 'npm' + + - name: Install dependencies + run: npm install + + - name: Test + run: npm run test \ No newline at end of file diff --git a/package.json b/package.json index 5ed6a9a..050aa00 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "build": "turbo run build", "dev": "turbo run dev", "lint": "turbo run lint", - "format": "prettier --write \"**/*.{ts,tsx,md}\"" + "format": "prettier --write \"**/*.{ts,tsx,md}\"", + "test": "turbo test" }, "devDependencies": { "@types/jest": "^29.5.8", From 53cdddaf4943a30f175d123bba4bff280d62a589 Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Sun, 19 Nov 2023 15:33:21 +0530 Subject: [PATCH 07/40] added tests for Escrow class --- packages/client/src/__mocks__/clientMocks.ts | 21 ++- packages/client/src/__mocks__/fixtures.ts | 10 +- .../src/escrow/__tests__/escrow.spec.ts | 124 ++++++++++++++++++ packages/client/src/escrow/index.ts | 5 +- packages/client/src/proposals/index.ts | 2 +- .../client/src/services/graphql/queries.ts | 12 ++ packages/client/src/services/index.ts | 20 +-- 7 files changed, 174 insertions(+), 20 deletions(-) create mode 100644 packages/client/src/escrow/__tests__/escrow.spec.ts diff --git a/packages/client/src/__mocks__/clientMocks.ts b/packages/client/src/__mocks__/clientMocks.ts index b16ad2b..531c473 100644 --- a/packages/client/src/__mocks__/clientMocks.ts +++ b/packages/client/src/__mocks__/clientMocks.ts @@ -1,6 +1,9 @@ +import { getPaymentsByService, getProtocolAndPlatformsFees } from "../escrow/graphql/queries"; import { getPlatformById, getProtocolById } from "../platform/graphql/queries"; import { getMintFees, getPaymentsForUser, getProfileByAddress, getProfileById, getProfiles, getUserTotalGains } from "../profile/graphql"; -import { mockGraphQlMintFeesResponse, mockGraphQlProtocolByIdResponse, mockGraphQlUsersResponse, testAddress, testGetProfilesResponse, testIpfsHash, testPlatformId, testPlatformResponse, testPlatformResponseWithArbitrator, testUserId, testUserPaymentsResponse, testUserResponse, testUserTotalGainsResponse } from "./fixtures"; +import { getProposalById } from "../proposals/graphql"; +import { getOne } from "../services/graphql/queries"; +import { mockGraphQlMintFeesResponse, mockGraphQlProtocolByIdResponse, mockGraphQlUsersResponse, testAddress, testChainId, testGetProfilesResponse, testIpfsHash, testPaymentsByServiceResponse, testPlatformId, testPlatformResponse, testPlatformResponseWithArbitrator, testProposalId, testProposalResponse, testProtocolAndPlatformResponse, testServiceId, testServiceResponse, testUserId, testUserPaymentsResponse, testUserResponse, testUserTotalGainsResponse } from "./fixtures"; export class MockGraphQLClient { get = jest.fn(async (query: string) => { @@ -40,6 +43,22 @@ export class MockGraphQLClient { return testPlatformResponseWithArbitrator; } + if (query === getProposalById(testProposalId)) { + return testProposalResponse; + } + + if (query === getProtocolAndPlatformsFees(testProposalResponse.data.proposal.service.platform.id, testProposalResponse.data.proposal.platform.id)) { + return testProtocolAndPlatformResponse; + } + + if (query === getOne(testServiceId)) { + return testServiceResponse; + } + + if (query === getPaymentsByService(testServiceId)) { + return testPaymentsByServiceResponse; + } + return { data: { "racoon": "bar" } }; }) diff --git a/packages/client/src/__mocks__/fixtures.ts b/packages/client/src/__mocks__/fixtures.ts index 2fb7e89..c82dbc3 100644 --- a/packages/client/src/__mocks__/fixtures.ts +++ b/packages/client/src/__mocks__/fixtures.ts @@ -1,4 +1,5 @@ export const testAddress = "0xRacoon"; +export const testCid = 'abcd'; export const testName = 'racoon'; export const testUserId = '2371'; export const testChainId = 137; @@ -67,4 +68,11 @@ export const testUserPaymentsResponse = { data: { payments: [{ "id": "0x3eb59738 export const testPlatformResponse = { "data": { "platform": { "id": "1", "address": "0xracoon", "name": "abcd", "createdAt": "1681454011", "updatedAt": "1681454011", "originServiceFeeRate": 0, "originValidatedProposalFeeRate": 0, "servicePostingFee": "0", "proposalPostingFee": "0", "arbitrator": "0x0000000000000000000000000000000000000000", "arbitratorExtraData": "0x00000000", "arbitrationFeeTimeout": "864000", "cid": null, "signer": "0xraqcoon", "description": null } } } -export const testPlatformResponseWithArbitrator = { "data": { "platform": { "id": "1", "address": "0xracoon", "name": "abcd", "createdAt": "1681454011", "updatedAt": "1681454011", "originServiceFeeRate": 0, "originValidatedProposalFeeRate": 0, "servicePostingFee": "0", "proposalPostingFee": "0", "arbitrator": "0xracoon", "arbitratorExtraData": "0x00000000", "arbitrationFeeTimeout": "864000", "cid": null, "signer": "0xraqcoon", "description": null } } } \ No newline at end of file +export const testPlatformResponseWithArbitrator = { "data": { "platform": { "id": "1", "address": "0xracoon", "name": "abcd", "createdAt": "1681454011", "updatedAt": "1681454011", "originServiceFeeRate": 0, "originValidatedProposalFeeRate": 0, "servicePostingFee": "0", "proposalPostingFee": "0", "arbitrator": "0xracoon", "arbitratorExtraData": "0x00000000", "arbitrationFeeTimeout": "864000", "cid": null, "signer": "0xraqcoon", "description": null } } } +export const testProposalId = '12-83' +export const testProposalResponse = { "data": { "proposal": { "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" } } } +export const testProtocolAndPlatformResponse = { "data": { "protocols": [{ "protocolEscrowFeeRate": 100 }], "servicePlatform": { "originServiceFeeRate": 0 }, "proposalPlatform": { "originValidatedProposalFeeRate": 0 } } } +export const testServiceId = '12'; +export const testAmount = BigInt('1000'); +export const testServiceResponse = { "data": { "service": { "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ", "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } } } }; +export const testPaymentsByServiceResponse = { "data": { "payments": [{ "id": "0xbae7cb57cef86c17a0ca0ca9af0f1b845912fe65448169f0a93a15e5e6dfae25-200", "amount": "10000000000000000000", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "paymentType": "Release", "transactionHash": "0xbae7cb57cef86c17a0ca0ca9af0f1b845912fe65448169f0a93a15e5e6dfae25", "createdAt": "1683204479" }] } } \ No newline at end of file diff --git a/packages/client/src/escrow/__tests__/escrow.spec.ts b/packages/client/src/escrow/__tests__/escrow.spec.ts new file mode 100644 index 0000000..0ad559b --- /dev/null +++ b/packages/client/src/escrow/__tests__/escrow.spec.ts @@ -0,0 +1,124 @@ + +import { Escrow } from '..'; +import { MockGraphQLClient, MockIPFSClient, MockViemClient } from '../../__mocks__/clientMocks'; +import { testAddress, testAmount, testChainId, testCid, testPlatformId, testProposalId, testProposalResponse, testProtocolAndPlatformResponse, testServiceId, testUserId } from '../../__mocks__/fixtures'; +// DO NOT remove this comments - they are needed for local testing +// import { getGraphQLConfig } from "../../config"; +// import GraphQLClient from "../../graphql"; + + +describe('Escrow', () => { + let escrow: any; + let mockGraphQLClient: any; + let mockIPFSClient: any; + let mockViemClient: any; + + beforeEach(() => { + mockGraphQLClient = new MockGraphQLClient(); + // DO NOT remove this comments - they are needed for local testing + // mockGraphQLClient = new GraphQLClient(getGraphQLConfig(137)) + mockIPFSClient = new MockIPFSClient(); + mockViemClient = new MockViemClient(); + escrow = new Escrow(mockGraphQLClient, mockIPFSClient, mockViemClient, testPlatformId, testChainId); + }); + + describe('approve', () => { + it('should successfully approve', async () => { + // Arrange + const serviceId = 'testServiceId'; + const proposalId = testProposalId; + const metaEvidenceCid = 'testMetaEvidenceCid'; + + // Act + const result = await escrow.approve(serviceId, proposalId, metaEvidenceCid); + + expect(result.tx).toEqual(testAddress) + expect(result.cid).toEqual(testCid) + + // Additional assertions... + }); + + it('should handle errors when proposal not found', async () => { + // Arrange + const serviceId = 'testServiceId'; + const proposalId = 'not-found'; + const metaEvidenceCid = 'testMetaEvidenceCid'; + + // Act and Assert + await expect(escrow.approve(serviceId, proposalId, metaEvidenceCid)).rejects.toThrow('Proposal not found'); + }); + + it('should handle error when platform data not found', async () => { + // Arrange + const serviceId = 'testServiceId'; + const proposalId = testProposalId; + const metaEvidenceCid = 'testMetaEvidenceCid'; + jest.spyOn(escrow, 'getProtocolAndPlatformsFees').mockResolvedValue(null); // Simulate proposal not found + + // Act and Assert + await expect(escrow.approve(serviceId, proposalId, metaEvidenceCid)).rejects.toThrow('Unable to fetch fees'); + + }) + + // Additional test cases... + }); + + describe('reimburse', () => { + it('should successfully reimburse', async () => { + // Arrange + const serviceId = testServiceId; + const userId = testUserId; // Example user ID + const amount = testAmount; // Example amount + + // Mock necessary dependencies and method calls + // ... + + // Act + const result = await escrow.reimburse(serviceId, userId, amount); + + // Assert + expect(result).toEqual(testAddress) + }); + + }) + + describe('getProtocolAndPlatformsFees', () => { + it('should fetch and return fees data', async () => { + // Arrange + const platformId1 = testProposalResponse.data.proposal.service.platform.id; + const platformId2 = testProposalResponse.data.proposal.platform.id; + + // Mock GraphQLClient responses + // ... + + // Act + const feesData = await escrow.getProtocolAndPlatformsFees(platformId1, platformId2); + + // Assert + expect(feesData).toEqual(testProtocolAndPlatformResponse.data) + + }); + + // Additional test cases for error scenarios... + }); + + + describe('getByService', () => { + it('should fetch and return service data', async () => { + // Arrange + const serviceId = testServiceId; + + // Mock GraphQLClient responses + // ... + + // Act + const serviceData = await escrow.getByService(serviceId); + + // Assert + expect(serviceData).toBeDefined(); + }); + + // Additional test cases for error scenarios... + }); + +}); \ No newline at end of file diff --git a/packages/client/src/escrow/index.ts b/packages/client/src/escrow/index.ts index 902d4ae..1e94d24 100644 --- a/packages/client/src/escrow/index.ts +++ b/packages/client/src/escrow/index.ts @@ -65,7 +65,7 @@ export class Escrow { console.log('SDK: fees', protocolAndPlatformsFees); - if (!protocolAndPlatformsFees.data) { + if (!protocolAndPlatformsFees) { throw Error('Unable to fetch fees'); } @@ -102,7 +102,6 @@ export class Escrow { approvalAmount, ); - // @ts-ignore const approvalTransactionReceipt = await this.viemClient.publicClient.waitForTransactionReceipt({ hash: approvalTransaction, @@ -198,7 +197,7 @@ export class Escrow { return response?.data || null; } - + public async getByService(serviceId: string, paymentType?: string): Promise { const query = getPaymentsByService(serviceId, paymentType); diff --git a/packages/client/src/proposals/index.ts b/packages/client/src/proposals/index.ts index 59143d7..f028b72 100644 --- a/packages/client/src/proposals/index.ts +++ b/packages/client/src/proposals/index.ts @@ -50,7 +50,7 @@ export class Proposal { public async getByUser(userId: string): Promise { const query = getAllProposalsByUser(userId) - + const response = await this.graphQlClient.get(query); return response?.data?.proposals || null diff --git a/packages/client/src/services/graphql/queries.ts b/packages/client/src/services/graphql/queries.ts index 58a1957..b0a1692 100644 --- a/packages/client/src/services/graphql/queries.ts +++ b/packages/client/src/services/graphql/queries.ts @@ -1,3 +1,4 @@ +import { serviceDescriptionQueryFields, serviceQueryFields } from '../../graphql'; import { IProps } from '../types'; export const getFilteredServiceDescriptionCondition = (params: IProps): string => { @@ -19,3 +20,14 @@ export const getFilteredServiceCondition = (params: IProps): string => { condition += '}'; return condition === ', where: {}' ? '' : condition; }; + +export const getOne = (id: string) => (` +{ + service(id: "${id}") { + ${serviceQueryFields} + description { + ${serviceDescriptionQueryFields} + } + } +} +`) \ No newline at end of file diff --git a/packages/client/src/services/index.ts b/packages/client/src/services/index.ts index c46a866..08452b8 100644 --- a/packages/client/src/services/index.ts +++ b/packages/client/src/services/index.ts @@ -7,6 +7,7 @@ import { ViemClient } from '../viem'; import { getFilteredServiceCondition, getFilteredServiceDescriptionCondition, + getOne, } from './graphql/queries'; import { ICreateServiceSignature, IProps, ServiceDetails } from './types'; @@ -49,16 +50,7 @@ export class Service { } public async getOne(id: string): Promise { - const query = ` - { - service(id: "${id}") { - ${serviceQueryFields} - description { - ${serviceDescriptionQueryFields} - } - } - } - `; + const query = getOne(id); const response = await this.graphQlClient.get(query); @@ -80,8 +72,8 @@ export class Service { const query = ` { services(orderBy: id, orderDirection: desc ${pagination} ${getFilteredServiceCondition( - params, - )}) { + params, + )}) { ${serviceQueryFields} description { ${serviceDescriptionQueryFields} @@ -101,8 +93,8 @@ export class Service { serviceDescriptionSearchRank( text: "${params.searchQuery}", orderBy: id orderDirection: desc ${pagination} ${getFilteredServiceDescriptionCondition( - params, - )} + params, + )} ){ ${serviceDescriptionQueryFields} service { From 88703789c3ef1e1ec8c63d8be50c7b7c3b25ef2f Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Sun, 19 Nov 2023 22:39:50 +0530 Subject: [PATCH 08/40] added tests for platform and proposals --- packages/client/src/__mocks__/clientMocks.ts | 19 +- packages/client/src/__mocks__/fixtures.ts | 20 +- .../src/platform/__tests__/platform.spec.ts | 186 ++++++++++++++++++ .../src/proposals/__tests__/proposals.spec.ts | 107 ++++++++++ 4 files changed, 326 insertions(+), 6 deletions(-) create mode 100644 packages/client/src/platform/__tests__/platform.spec.ts create mode 100644 packages/client/src/proposals/__tests__/proposals.spec.ts diff --git a/packages/client/src/__mocks__/clientMocks.ts b/packages/client/src/__mocks__/clientMocks.ts index 531c473..c0ffc88 100644 --- a/packages/client/src/__mocks__/clientMocks.ts +++ b/packages/client/src/__mocks__/clientMocks.ts @@ -1,9 +1,9 @@ import { getPaymentsByService, getProtocolAndPlatformsFees } from "../escrow/graphql/queries"; -import { getPlatformById, getProtocolById } from "../platform/graphql/queries"; +import { getPlatformById, getPlatformsByOwner, getProtocolById } from "../platform/graphql/queries"; import { getMintFees, getPaymentsForUser, getProfileByAddress, getProfileById, getProfiles, getUserTotalGains } from "../profile/graphql"; -import { getProposalById } from "../proposals/graphql"; +import { getAllProposalsByServiceId, getAllProposalsByUser, getProposalById } from "../proposals/graphql"; import { getOne } from "../services/graphql/queries"; -import { mockGraphQlMintFeesResponse, mockGraphQlProtocolByIdResponse, mockGraphQlUsersResponse, testAddress, testChainId, testGetProfilesResponse, testIpfsHash, testPaymentsByServiceResponse, testPlatformId, testPlatformResponse, testPlatformResponseWithArbitrator, testProposalId, testProposalResponse, testProtocolAndPlatformResponse, testServiceId, testServiceResponse, testUserId, testUserPaymentsResponse, testUserResponse, testUserTotalGainsResponse } from "./fixtures"; +import { mockGraphQlMintFeesResponse, mockGraphQlProtocolByIdResponse, mockGraphQlUsersResponse, testAddress, testChainId, testGetProfilesResponse, testIpfsHash, testOwnerAddress, testPaymentsByServiceResponse, testPlatformId, testPlatformResponse, testPlatformResponseWithArbitrator, testPlatformsByOwnerResponse, testProposalId, testProposalResponse, testProposalsByServiceId, testProposalsByUser, testProtocolAndPlatformResponse, testServiceId, testServiceResponse, testUserId, testUserPaymentsResponse, testUserResponse, testUserTotalGainsResponse } from "./fixtures"; export class MockGraphQLClient { get = jest.fn(async (query: string) => { @@ -59,6 +59,18 @@ export class MockGraphQLClient { return testPaymentsByServiceResponse; } + if (query === getPlatformsByOwner(testOwnerAddress)) { + return testPlatformsByOwnerResponse; + } + + if (query === getAllProposalsByServiceId(testServiceId)) { + return testProposalsByServiceId; + } + + if (query === getAllProposalsByUser(testUserId)) { + return testProposalsByUser; + } + return { data: { "racoon": "bar" } }; }) @@ -66,6 +78,7 @@ export class MockGraphQLClient { export class MockViemClient { writeContract = jest.fn(async () => testAddress) + chainId = 137; readContract = jest.fn(async () => "randomData") publicClient = { readContract: jest.fn(async () => "randomData") diff --git a/packages/client/src/__mocks__/fixtures.ts b/packages/client/src/__mocks__/fixtures.ts index c82dbc3..3a7becd 100644 --- a/packages/client/src/__mocks__/fixtures.ts +++ b/packages/client/src/__mocks__/fixtures.ts @@ -1,5 +1,4 @@ export const testAddress = "0xRacoon"; -export const testCid = 'abcd'; export const testName = 'racoon'; export const testUserId = '2371'; export const testChainId = 137; @@ -60,7 +59,8 @@ export const mockGraphQlProtocolByIdResponse = { } } } -export const testIpfsHash = 'ipfsHash'; +export const testIpfsHash = 'abcd'; +export const testCid = testIpfsHash; export const testProfileData = { name: testName, about: testAbout }; export const testGetProfilesResponse = { "data": { "users": [{ "id": "11962", "address": "0x02289d0ebf8836e6f98af170b88b9f8eb889e2c6", "handle": "racoon", "userStats": { "numReceivedReviews": "0" }, "rating": "0" }] } } export const testUserTotalGainsResponse = { data: { user: { totalGains: [{ "id": "2371-0x2791bca1f2de4661ed88a30c99a7a9449aa84174", "totalGain": "850000000", "token": { "id": "0xracoon", "name": "USD Coin (PoS)", "symbol": "USDC", "decimals": "6" } }] } } } @@ -75,4 +75,18 @@ export const testProtocolAndPlatformResponse = { "data": { "protocols": [{ "prot export const testServiceId = '12'; export const testAmount = BigInt('1000'); export const testServiceResponse = { "data": { "service": { "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ", "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } } } }; -export const testPaymentsByServiceResponse = { "data": { "payments": [{ "id": "0xbae7cb57cef86c17a0ca0ca9af0f1b845912fe65448169f0a93a15e5e6dfae25-200", "amount": "10000000000000000000", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "paymentType": "Release", "transactionHash": "0xbae7cb57cef86c17a0ca0ca9af0f1b845912fe65448169f0a93a15e5e6dfae25", "createdAt": "1683204479" }] } } \ No newline at end of file +export const testPaymentsByServiceResponse = { "data": { "payments": [{ "id": "0xbae7cb57cef86c17a0ca0ca9af0f1b845912fe65448169f0a93a15e5e6dfae25-200", "amount": "10000000000000000000", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "paymentType": "Release", "transactionHash": "0xbae7cb57cef86c17a0ca0ca9af0f1b845912fe65448169f0a93a15e5e6dfae25", "createdAt": "1683204479" }] } } +export const testPlatformDetails = { + about: 'test data', + website: 'example.com', + video_url: 'example.com', + image_url: 'example.com' +} + +export const testOwnerAddress = '0xOwnerAddress'; +export const testPlatformsByOwnerResponse = { "data": { "platforms": [{ "id": "1", "address": "0x4444444e2f8ccd0e323c959b02a93561b911f9b6", "name": "workx", "createdAt": "1681454011", "updatedAt": "1681454011", "originServiceFeeRate": 0, "originValidatedProposalFeeRate": 0, "servicePostingFee": "0", "proposalPostingFee": "0", "arbitrator": "0x0000000000000000000000000000000000000000", "arbitratorExtraData": "0x00000000", "arbitrationFeeTimeout": "864000", "cid": null, "signer": "0x4444444e2f8ccd0e323c959b02a93561b911f9b6", "description": null }] } } +export const testProposalsByServiceId = { "data": { "proposals": [{ "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" }] } } +export const testProposalsByUser = { "data": { "proposals": [{ "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" }] } } +export const testProposalDetails = { about: 'test about', video_url: 'hello world' } +export const testExpirationDate = '123456'; +export const testSignature = ''; \ No newline at end of file diff --git a/packages/client/src/platform/__tests__/platform.spec.ts b/packages/client/src/platform/__tests__/platform.spec.ts new file mode 100644 index 0000000..dcabc36 --- /dev/null +++ b/packages/client/src/platform/__tests__/platform.spec.ts @@ -0,0 +1,186 @@ + +import { parseEther } from 'viem'; +import { Platform } from '..'; +import { getChainConfig, getGraphQLConfig } from '../../config'; +import { FEE_RATE_DIVIDER } from '../../constants'; +import { MockGraphQLClient, MockIPFSClient, MockViemClient } from '../../__mocks__/clientMocks'; +import { testAddress, testChainId, testCid, testIpfsHash, testOwnerAddress, testPlatformDetails, testPlatformId, testPlatformResponse, testPlatformsByOwnerResponse, testProtocolAndPlatformResponse } from '../../__mocks__/fixtures'; +import { getPlatformById } from '../graphql/queries'; + +describe('Platform', () => { + let platform: Platform; + let mockGraphQLClient: any; + let mockIPFSClient: any; + let mockViemClient: any; + + beforeEach(() => { + mockGraphQLClient = new MockGraphQLClient(); + mockIPFSClient = new MockIPFSClient(); + mockViemClient = new MockViemClient(); + platform = new Platform(mockGraphQLClient, mockViemClient, testPlatformId, mockIPFSClient); + }); + + describe('getOne', () => { + it('should fetch and return platform details', async () => { + // Arrange and Act + const platformDetails = await platform.getOne(testPlatformId.toString()); + + // Assert + expect(platformDetails).toBeDefined(); + expect(mockGraphQLClient.get).toHaveBeenCalledWith(getPlatformById(testPlatformId.toString())); + expect(platformDetails).toEqual(testPlatformResponse.data.platform); + }); + }); + + describe('upload', () => { + it('should upload platform details to IPFS', async () => { + // Arrange - Platform details to upload + + // Act + const cid = await platform.upload(testPlatformDetails); + + // Assert + expect(cid).toEqual(testIpfsHash) + }); + + }); + + describe('getByOwner', () => { + it('should retrieve platforms for a given owner address', async () => { + // Arrange - Owner's address + const ownerAddress = testOwnerAddress; + + // Act + const platforms = await platform.getByOwner(ownerAddress); + + // Assert + expect(platforms).toEqual(testPlatformsByOwnerResponse.data.platforms); + }); + }); + + describe('update', () => { + it('should update the platform details', async () => { + // Arrange + const platformDetails = testPlatformDetails; + + // Act + const result = await platform.update(platformDetails); + + // Assert + expect(result.cid).toEqual(testIpfsHash); + expect(result.tx).toEqual(testAddress); + + }) + }) + + describe('setFeeTimeout', () => { + it('should set the arbitration fee timeout of the platform', async () => { + // Arrange + const timeout = 1; + + // Act + const result = await platform.setFeeTimeout(timeout); + + // Assert + expect(mockViemClient.writeContract).toHaveBeenCalledWith('talentLayerPlatformId', + 'updateArbitrationFeeTimeout', + [testPlatformId, timeout]); + expect(result).toEqual(testAddress); + + }) + }) + + describe('updateOriginServiceFeeRate', () => { + it('should update the origin platform service fee rate', async () => { + // Arrange + const feeRate = 1; + const transformedFeeRate = Math.round((Number(feeRate) * FEE_RATE_DIVIDER) / 100); + + // Act + const result = await platform.updateOriginServiceFeeRate(feeRate); + + // Assert + expect(mockViemClient.writeContract).toHaveBeenCalledWith('talentLayerPlatformId', + 'updateOriginServiceFeeRate', + [testPlatformId, transformedFeeRate]); + expect(result).toEqual(testAddress); + + }) + }) + + describe('updateOriginValidatedProposalFeeRate', () => { + it('should update the origin platform validated proposal fee rate', async () => { + // Arrange + const feeRate = 1; + const transformedFeeRate = Math.round((Number(feeRate) * FEE_RATE_DIVIDER) / 100); + + // Act + const result = await platform.updateOriginValidatedProposalFeeRate(feeRate); + + // Assert + expect(mockViemClient.writeContract).toHaveBeenCalledWith('talentLayerPlatformId', + 'updateOriginValidatedProposalFeeRate', + [testPlatformId, transformedFeeRate]); + expect(result).toEqual(testAddress); + + }) + }) + + describe('updateArbitrator', () => { + it('should update the arbitrator of the platform', async () => { + // Arrange + const chainConfig = getChainConfig(testChainId); + console.log('chain config: ', chainConfig); + const contract = chainConfig.contracts['talentLayerArbitrator']; + const talentLayerArbitratorAddress = contract.address; + + // Act + const response = await platform.updateArbitrator(talentLayerArbitratorAddress); + + // Assert + expect(mockViemClient.writeContract).toHaveBeenLastCalledWith( + 'talentLayerPlatformId', + 'updateArbitrator', + [testPlatformId, talentLayerArbitratorAddress, ''] + ) + expect(response).toEqual(testAddress); + + }) + }) + + describe('updateServicePostingFee', () => { + it('should update the platform service posting fee rate', async () => { + // Arrange + const feeRate = 1; + const transformedFeeRate = parseEther(feeRate.toString()); + + // Act + const result = await platform.updateServicePostingFee(feeRate); + + // Assert + expect(mockViemClient.writeContract).toHaveBeenCalledWith('talentLayerPlatformId', + 'updateServicePostingFee', + [testPlatformId, transformedFeeRate]); + expect(result).toEqual(testAddress); + + }) + }) + + describe('updateProposalPostingFee', () => { + it('should update the platform proposal posting fee rate', async () => { + // Arrange + const feeRate = 1; + const transformedFeeRate = parseEther(feeRate.toString()); + + // Act + const result = await platform.updateProposalPostingFee(feeRate); + + // Assert + expect(mockViemClient.writeContract).toHaveBeenCalledWith('talentLayerPlatformId', + 'updateProposalPostingFee', + [testPlatformId, transformedFeeRate]); + expect(result).toEqual(testAddress); + + }) + }) +}); diff --git a/packages/client/src/proposals/__tests__/proposals.spec.ts b/packages/client/src/proposals/__tests__/proposals.spec.ts new file mode 100644 index 0000000..245f813 --- /dev/null +++ b/packages/client/src/proposals/__tests__/proposals.spec.ts @@ -0,0 +1,107 @@ + +import { Proposal } from '..'; +import { MockGraphQLClient, MockIPFSClient, MockViemClient } from '../../__mocks__/clientMocks'; +import { testAddress, testAmount, testChainId, testCid, testExpirationDate, testIpfsHash, testOwnerAddress, testPlatformDetails, testPlatformId, testPlatformResponse, testPlatformsByOwnerResponse, testProposalDetails, testProposalId, testProposalResponse, testProposalsByServiceId, testProposalsByUser, testProtocolAndPlatformResponse, testServiceId, testSignature, testUserId } from '../../__mocks__/fixtures'; +// Additional imports... + +describe('Platform', () => { + let proposal: Proposal; + let mockGraphQLClient: any; + let mockIPFSClient: any; + let mockViemClient: any; + + beforeEach(() => { + mockGraphQLClient = new MockGraphQLClient(); + // mockGraphQLClient = new GraphQLClient(getGraphQLConfig(137)) + mockIPFSClient = new MockIPFSClient(); + mockViemClient = new MockViemClient(); + proposal = new Proposal(mockGraphQLClient, mockIPFSClient, mockViemClient, testPlatformId, 'example.com'); + }); + + describe('getOne', () => { + it('should return proposal details based on id', async () => { + // Arrange + const proposalId = testProposalId; + + // Act + const response = await proposal.getOne(proposalId); + + //Assert + expect(response).toEqual(testProposalResponse.data.proposal); + }) + }) + + describe('getByServiceId', () => { + it('should return proposal details based on service id', async () => { + // Arrange + const serviceId = testServiceId; + + // Act + const response = await proposal.getByServiceId(serviceId); + + //Assert + expect(response).toEqual(testProposalsByServiceId.data.proposals); + }) + }) + + describe('getByUser', () => { + it('should return all proposal for a user', async () => { + // Arrange + const userId = testUserId; + + // Act + const resposne = await proposal.getByUser(userId); + + expect(resposne).toEqual(testProposalsByUser.data.proposals) + }) + }) + + describe('update', () => { + it('should update proposal Details', async () => { + // Arrange + const proposalDetails = testProposalDetails; + const userId = testUserId; + const serviceId = testServiceId; + const rateToken = testAddress; + const rateAmount = testAmount; + const expirationDate = testExpirationDate; + + // Act + const resposne = await proposal.update(proposalDetails, userId, serviceId, rateToken, rateAmount.toString(), expirationDate) + + // Assert + expect(mockIPFSClient.post).toHaveBeenCalledWith(JSON.stringify(proposalDetails)); + expect(mockViemClient.writeContract).toHaveBeenLastCalledWith( + 'talentLayerService', + 'updateProposal', + [userId, serviceId, rateToken, rateAmount.toString(), testIpfsHash, expirationDate] + ) + }) + }) + + describe('create', () => { + it('should create a proposal for a service', async () => { + // Arrange + const proposalDetails = testProposalDetails; + const userId = testUserId; + const serviceId = testServiceId; + const rateToken = testAddress; + const rateAmount = testAmount; + const expirationDate = testExpirationDate; + const signatureResponse = testSignature; + jest.spyOn(proposal, 'getSignature').mockResolvedValueOnce(signatureResponse); + + // Act + const resposne = await proposal.create(proposalDetails, userId, serviceId, rateToken, rateAmount.toString(), expirationDate) + + // Assert + expect(mockViemClient.writeContract).toHaveBeenCalledWith( + 'talentLayerService', + 'createProposal', + [userId, serviceId, rateToken, rateAmount.toString(), testPlatformId, testIpfsHash, expirationDate, signatureResponse], + BigInt(testPlatformResponse.data.platform.proposalPostingFee), + ) + + }) + }) +}); From ac97c8ec26eff5fc7a37bf4ca5b850e590a9e1d4 Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Mon, 20 Nov 2023 00:18:30 +0530 Subject: [PATCH 09/40] added tests for escrow services and utils --- packages/client/src/__mocks__/clientMocks.ts | 15 +++- packages/client/src/__mocks__/fixtures.ts | 23 ++++- .../src/escrow/__tests__/escrow.spec.ts | 87 ++++++++++++++---- packages/client/src/escrow/index.ts | 4 +- .../src/services/__tests__/services.spec.ts | 89 +++++++++++++++++++ .../client/src/services/graphql/queries.ts | 45 +++++++++- packages/client/src/services/index.ts | 43 ++------- .../client/src/utils/__tests__/utils.spec.ts | 27 ++++++ 8 files changed, 271 insertions(+), 62 deletions(-) create mode 100644 packages/client/src/services/__tests__/services.spec.ts create mode 100644 packages/client/src/utils/__tests__/utils.spec.ts diff --git a/packages/client/src/__mocks__/clientMocks.ts b/packages/client/src/__mocks__/clientMocks.ts index c0ffc88..9f2be83 100644 --- a/packages/client/src/__mocks__/clientMocks.ts +++ b/packages/client/src/__mocks__/clientMocks.ts @@ -2,8 +2,8 @@ import { getPaymentsByService, getProtocolAndPlatformsFees } from "../escrow/gra import { getPlatformById, getPlatformsByOwner, getProtocolById } from "../platform/graphql/queries"; import { getMintFees, getPaymentsForUser, getProfileByAddress, getProfileById, getProfiles, getUserTotalGains } from "../profile/graphql"; import { getAllProposalsByServiceId, getAllProposalsByUser, getProposalById } from "../proposals/graphql"; -import { getOne } from "../services/graphql/queries"; -import { mockGraphQlMintFeesResponse, mockGraphQlProtocolByIdResponse, mockGraphQlUsersResponse, testAddress, testChainId, testGetProfilesResponse, testIpfsHash, testOwnerAddress, testPaymentsByServiceResponse, testPlatformId, testPlatformResponse, testPlatformResponseWithArbitrator, testPlatformsByOwnerResponse, testProposalId, testProposalResponse, testProposalsByServiceId, testProposalsByUser, testProtocolAndPlatformResponse, testServiceId, testServiceResponse, testUserId, testUserPaymentsResponse, testUserResponse, testUserTotalGainsResponse } from "./fixtures"; +import { getOne, getServices, searchServices } from "../services/graphql/queries"; +import { mockGraphQlMintFeesResponse, mockGraphQlProtocolByIdResponse, mockGraphQlUsersResponse, testAddress, testChainId, testGetProfilesResponse, testIpfsHash, testOwnerAddress, testPaymentsByServiceResponse, testPlatformId, testPlatformResponse, testPlatformResponseWithArbitrator, testPlatformsByOwnerResponse, testProposalId, testProposalIdWithDifferentRateToken, testProposalResponse, testProposalResponseWithDifferentRateToken, testProposalsByServiceId, testProposalsByUser, testProtocolAndPlatformResponse, testSearchServiceProps, testSearchServicesResponse, testServiceId, testServiceResponse, testUserId, testUserPaymentsResponse, testUserResponse, testUserTotalGainsResponse } from "./fixtures"; export class MockGraphQLClient { get = jest.fn(async (query: string) => { @@ -47,6 +47,10 @@ export class MockGraphQLClient { return testProposalResponse; } + if (query === getProposalById(testProposalIdWithDifferentRateToken)) { + return testProposalResponseWithDifferentRateToken; + } + if (query === getProtocolAndPlatformsFees(testProposalResponse.data.proposal.service.platform.id, testProposalResponse.data.proposal.platform.id)) { return testProtocolAndPlatformResponse; } @@ -71,6 +75,10 @@ export class MockGraphQLClient { return testProposalsByUser; } + if (query === searchServices(testSearchServiceProps) || query === getServices(testSearchServiceProps)) { + return testSearchServicesResponse; + } + return { data: { "racoon": "bar" } }; }) @@ -81,7 +89,8 @@ export class MockViemClient { chainId = 137; readContract = jest.fn(async () => "randomData") publicClient = { - readContract: jest.fn(async () => "randomData") + readContract: jest.fn(async () => "randomData"), + waitForTransactionReceipt: jest.fn(async () => ({ status: 'success' })) } } diff --git a/packages/client/src/__mocks__/fixtures.ts b/packages/client/src/__mocks__/fixtures.ts index 3a7becd..5e961a5 100644 --- a/packages/client/src/__mocks__/fixtures.ts +++ b/packages/client/src/__mocks__/fixtures.ts @@ -1,3 +1,6 @@ +import { ServiceStatusEnum } from "../services/enums"; +import { IProps } from "../services/types"; + export const testAddress = "0xRacoon"; export const testName = 'racoon'; export const testUserId = '2371'; @@ -69,12 +72,22 @@ export const testUserPaymentsResponse = { data: { payments: [{ "id": "0x3eb59738 export const testPlatformResponse = { "data": { "platform": { "id": "1", "address": "0xracoon", "name": "abcd", "createdAt": "1681454011", "updatedAt": "1681454011", "originServiceFeeRate": 0, "originValidatedProposalFeeRate": 0, "servicePostingFee": "0", "proposalPostingFee": "0", "arbitrator": "0x0000000000000000000000000000000000000000", "arbitratorExtraData": "0x00000000", "arbitrationFeeTimeout": "864000", "cid": null, "signer": "0xraqcoon", "description": null } } } export const testPlatformResponseWithArbitrator = { "data": { "platform": { "id": "1", "address": "0xracoon", "name": "abcd", "createdAt": "1681454011", "updatedAt": "1681454011", "originServiceFeeRate": 0, "originValidatedProposalFeeRate": 0, "servicePostingFee": "0", "proposalPostingFee": "0", "arbitrator": "0xracoon", "arbitratorExtraData": "0x00000000", "arbitrationFeeTimeout": "864000", "cid": null, "signer": "0xraqcoon", "description": null } } } -export const testProposalId = '12-83' -export const testProposalResponse = { "data": { "proposal": { "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" } } } +export const testProposalId = '12-83'; +export const testProposalIdWithDifferentRateToken = '12-84'; +export const testProposalResponse = { "data": { "proposal": { "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" } } }; +export const testProposalResponseWithDifferentRateToken = { "data": { "proposal": { "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": testAddress }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" } } } export const testProtocolAndPlatformResponse = { "data": { "protocols": [{ "protocolEscrowFeeRate": 100 }], "servicePlatform": { "originServiceFeeRate": 0 }, "proposalPlatform": { "originValidatedProposalFeeRate": 0 } } } export const testServiceId = '12'; export const testAmount = BigInt('1000'); export const testServiceResponse = { "data": { "service": { "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ", "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } } } }; +export const testSearchServicesResponse = { data: { "services": [{ "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ", "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } }] } } +export const testServiceDetails = { + title: 'test title', + about: 'test about', + keywords: 'web3,racoon', + rateToken: testAddress, + rateAmount: testAmount.toString() +} export const testPaymentsByServiceResponse = { "data": { "payments": [{ "id": "0xbae7cb57cef86c17a0ca0ca9af0f1b845912fe65448169f0a93a15e5e6dfae25-200", "amount": "10000000000000000000", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "paymentType": "Release", "transactionHash": "0xbae7cb57cef86c17a0ca0ca9af0f1b845912fe65448169f0a93a15e5e6dfae25", "createdAt": "1683204479" }] } } export const testPlatformDetails = { about: 'test data', @@ -89,4 +102,8 @@ export const testProposalsByServiceId = { "data": { "proposals": [{ "id": testPr export const testProposalsByUser = { "data": { "proposals": [{ "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" }] } } export const testProposalDetails = { about: 'test about', video_url: 'hello world' } export const testExpirationDate = '123456'; -export const testSignature = ''; \ No newline at end of file +export const testSignature = ''; +export const testSearchServiceProps: IProps = { + serviceStatus: ServiceStatusEnum.Opened +} +export const testMetaEvidenceCid = 'testMetaEvidenceCid'; \ No newline at end of file diff --git a/packages/client/src/escrow/__tests__/escrow.spec.ts b/packages/client/src/escrow/__tests__/escrow.spec.ts index 0ad559b..e62da85 100644 --- a/packages/client/src/escrow/__tests__/escrow.spec.ts +++ b/packages/client/src/escrow/__tests__/escrow.spec.ts @@ -1,7 +1,7 @@ import { Escrow } from '..'; import { MockGraphQLClient, MockIPFSClient, MockViemClient } from '../../__mocks__/clientMocks'; -import { testAddress, testAmount, testChainId, testCid, testPlatformId, testProposalId, testProposalResponse, testProtocolAndPlatformResponse, testServiceId, testUserId } from '../../__mocks__/fixtures'; +import { testAddress, testAmount, testChainId, testCid, testIpfsHash, testMetaEvidenceCid, testPlatformId, testProposalId, testProposalIdWithDifferentRateToken, testProposalResponse, testProtocolAndPlatformResponse, testServiceId, testServiceResponse, testUserId } from '../../__mocks__/fixtures'; // DO NOT remove this comments - they are needed for local testing // import { getGraphQLConfig } from "../../config"; // import GraphQLClient from "../../graphql"; @@ -25,24 +25,68 @@ describe('Escrow', () => { describe('approve', () => { it('should successfully approve', async () => { // Arrange - const serviceId = 'testServiceId'; + const serviceId = testServiceId; const proposalId = testProposalId; - const metaEvidenceCid = 'testMetaEvidenceCid'; + const metaEvidenceCid = testMetaEvidenceCid; // Act const result = await escrow.approve(serviceId, proposalId, metaEvidenceCid); expect(result.tx).toEqual(testAddress) expect(result.cid).toEqual(testCid) - - // Additional assertions... }); + it('should successfully approve with a non-native approved rateToken', async () => { + // Arrange + const serviceId = testServiceId; + const proposalId = testProposalIdWithDifferentRateToken; + const metaEvidenceCid = testMetaEvidenceCid; + escrow.erc20 = { + ...escrow.erc20, // Spread the existing properties + + checkAllowance: jest.fn(async () => BigInt('10100000000000000001')) + }; + + console.log('checking escrow erc20: ', escrow.erc20.checkAllowance) + + // Act + const result = await escrow.approve(serviceId, proposalId, metaEvidenceCid); + + // Assert + expect(result.tx).toEqual(testAddress) + expect(result.cid).toEqual(testCid) + }) + + it('should successfully approve with a non-native unapproved rateToken', async () => { + // Arrange + const serviceId = testServiceId; + const proposalId = testProposalIdWithDifferentRateToken; + const metaEvidenceCid = testMetaEvidenceCid; + escrow.erc20 = { + ...escrow.erc20, // Spread the existing properties + + checkAllowance: jest.fn(async () => BigInt('10000000000000000000')), + approve: jest.fn(async () => testAddress) + }; + + // Act + const result = await escrow.approve(serviceId, proposalId, metaEvidenceCid); + + // Assert + expect(mockViemClient.writeContract).toHaveBeenCalledWith( + 'talentLayerEscrow', + 'createTransaction', + [parseInt(serviceId, 10), parseInt(testProposalResponse.data.proposal.seller.id, 10), metaEvidenceCid, testIpfsHash] + ) + expect(result.tx).toEqual(testAddress) + expect(result.cid).toEqual(testCid) + }) + it('should handle errors when proposal not found', async () => { // Arrange - const serviceId = 'testServiceId'; + const serviceId = testServiceId; const proposalId = 'not-found'; - const metaEvidenceCid = 'testMetaEvidenceCid'; + const metaEvidenceCid = testMetaEvidenceCid; // Act and Assert await expect(escrow.approve(serviceId, proposalId, metaEvidenceCid)).rejects.toThrow('Proposal not found'); @@ -59,8 +103,6 @@ describe('Escrow', () => { await expect(escrow.approve(serviceId, proposalId, metaEvidenceCid)).rejects.toThrow('Unable to fetch fees'); }) - - // Additional test cases... }); describe('reimburse', () => { @@ -98,8 +140,6 @@ describe('Escrow', () => { expect(feesData).toEqual(testProtocolAndPlatformResponse.data) }); - - // Additional test cases for error scenarios... }); @@ -108,17 +148,32 @@ describe('Escrow', () => { // Arrange const serviceId = testServiceId; - // Mock GraphQLClient responses - // ... - // Act const serviceData = await escrow.getByService(serviceId); // Assert expect(serviceData).toBeDefined(); }); - - // Additional test cases for error scenarios... }); + describe('release', () => { + it('should release payment', async () => { + // Arrange + const serviceId = testServiceId; + const amount = testAmount; + const userId = testUserId; + + // Act + const resposne = await escrow.release(serviceId, amount, userId); + + // Assert + expect(mockViemClient.writeContract).toHaveBeenCalledWith( + 'talentLayerEscrow', + 'release', + [userId, parseInt(testServiceResponse.data.service.transaction.id), amount.toString()] + ) + + }) + }) + }); \ No newline at end of file diff --git a/packages/client/src/escrow/index.ts b/packages/client/src/escrow/index.ts index 1e94d24..d19d6e4 100644 --- a/packages/client/src/escrow/index.ts +++ b/packages/client/src/escrow/index.ts @@ -44,7 +44,7 @@ export class Escrow { this.platformID, ); const proposal = await proposalInstance.getOne(proposalId); - const erc20 = new ERC20(this.ipfsClient, this.viemClient, this.platformID, this.chainId); + const erc20 = this.erc20; if (!proposal) { throw new Error('Proposal not found'); @@ -76,7 +76,7 @@ export class Escrow { protocolAndPlatformsFees.protocols[0].protocolEscrowFeeRate, ); - console.log('SDK: escrow seeking approval for amount: ', approvalAmount); + console.log('SDK: escrow seeking approval for amount: ', approvalAmount.toString()); if (proposal.rateToken.address === RateToken.NATIVE) { tx = await this.viemClient.writeContract( diff --git a/packages/client/src/services/__tests__/services.spec.ts b/packages/client/src/services/__tests__/services.spec.ts new file mode 100644 index 0000000..415e3f0 --- /dev/null +++ b/packages/client/src/services/__tests__/services.spec.ts @@ -0,0 +1,89 @@ + +import { Service } from '..'; +import { getPlatformById } from '../../platform/graphql/queries'; +import { MockGraphQLClient, MockIPFSClient, MockViemClient } from '../../__mocks__/clientMocks'; +import { testAddress, testIpfsHash, testPlatformId, testPlatformResponse, testSearchServiceProps, testSearchServicesResponse, testServiceDetails, testServiceId, testServiceResponse, testSignature, testUserId } from '../../__mocks__/fixtures'; + +describe('Platform', () => { + let service: Service; + let mockGraphQLClient: any; + let mockIPFSClient: any; + let mockViemClient: any; + + beforeEach(() => { + mockGraphQLClient = new MockGraphQLClient(); + // mockGraphQLClient = new GraphQLClient(getGraphQLConfig(137)) + mockIPFSClient = new MockIPFSClient(); + mockViemClient = new MockViemClient(); + service = new Service(mockGraphQLClient, mockIPFSClient, mockViemClient, testPlatformId, 'example.com'); + }); + + describe('getOne', () => { + it('should return details of a service by id', async () => { + // Arrange + const serviceId = testServiceId; + + // Act + const response = await service.getOne(serviceId); + + // Assert + expect(response).toEqual(testServiceResponse.data.service) + + }) + }) + + describe('create', () => { + it('should create a new service', async () => { + // Arrange + const serviceDetails = testServiceDetails; + const userId = testUserId; + const platformID = testPlatformId; + jest.spyOn(service, 'getServiceSignature').mockResolvedValue(testSignature) + + // Act + const response = await service.create(serviceDetails, userId, platformID); + + // Assert + expect(response.cid).toEqual(testIpfsHash); + expect(response.tx).toEqual(testAddress); + expect(mockGraphQLClient.get).toHaveBeenCalledWith(getPlatformById(platformID.toString())); + expect(mockViemClient.writeContract).toHaveBeenCalledWith( + 'talentLayerService', + 'createService', + [userId, platformID, testIpfsHash, testSignature], + BigInt(testPlatformResponse.data.platform.servicePostingFee), + + ); + + }) + }) + + describe('search', () => { + it('should reaturn services based on criteria', async () => { + // Arranage + const props = testSearchServiceProps; + + // Act + const response = await service.search(props); + + // Assert + expect(response).toEqual(testSearchServicesResponse) + + }) + }) + + describe('getServices', () => { + it('should return services based on criteria', async () => { + // Arranage + const props = testSearchServiceProps; + + // Act + const response = await service.getServices(props); + + // Assert + expect(response).toEqual(testSearchServicesResponse) + + }) + }) + +}); diff --git a/packages/client/src/services/graphql/queries.ts b/packages/client/src/services/graphql/queries.ts index b0a1692..e25598e 100644 --- a/packages/client/src/services/graphql/queries.ts +++ b/packages/client/src/services/graphql/queries.ts @@ -30,4 +30,47 @@ export const getOne = (id: string) => (` } } } -`) \ No newline at end of file +`) + +export const getServices = (params: IProps) => { + const pagination = params.numberPerPage + ? 'first: ' + params.numberPerPage + ', skip: ' + params.offset + : ''; + + const query = ` + { + services(orderBy: id, orderDirection: desc ${pagination} ${getFilteredServiceCondition( + params, + )}) { + ${serviceQueryFields} + description { + ${serviceDescriptionQueryFields} + } + } + }`; + + return query; +} + +export const searchServices = (params: IProps) => { + const pagination = params.numberPerPage + ? 'first: ' + params.numberPerPage + ' skip: ' + params.offset + : ''; + + const query = ` + { + serviceDescriptionSearchRank( + text: "${params.searchQuery}", + orderBy: id orderDirection: desc ${pagination} ${getFilteredServiceDescriptionCondition( + params, + )} + ){ + ${serviceDescriptionQueryFields} + service { + ${serviceQueryFields} + } + } + }`; + + return query; +} \ No newline at end of file diff --git a/packages/client/src/services/index.ts b/packages/client/src/services/index.ts index 08452b8..e4ff668 100644 --- a/packages/client/src/services/index.ts +++ b/packages/client/src/services/index.ts @@ -1,13 +1,13 @@ -import GraphQLClient, { serviceDescriptionQueryFields, serviceQueryFields } from '../graphql'; +import GraphQLClient from '../graphql'; import IPFSClient from '../ipfs'; import { getPlatformById } from '../platform/graphql/queries'; import { ClientTransactionResponse } from '../types'; import { getSignature } from '../utils/signature'; import { ViemClient } from '../viem'; import { - getFilteredServiceCondition, - getFilteredServiceDescriptionCondition, getOne, + getServices, + searchServices, } from './graphql/queries'; import { ICreateServiceSignature, IProps, ServiceDetails } from './types'; @@ -66,43 +66,12 @@ export class Service { } public async getServices(params: IProps): Promise { - const pagination = params.numberPerPage - ? 'first: ' + params.numberPerPage + ', skip: ' + params.offset - : ''; - const query = ` - { - services(orderBy: id, orderDirection: desc ${pagination} ${getFilteredServiceCondition( - params, - )}) { - ${serviceQueryFields} - description { - ${serviceDescriptionQueryFields} - } - } - }`; - - return this.graphQlClient.get(query); + + return this.graphQlClient.get(getServices(params)); } public async search(params: IProps): Promise { - const pagination = params.numberPerPage - ? 'first: ' + params.numberPerPage + ' skip: ' + params.offset - : ''; - const query = ` - { - serviceDescriptionSearchRank( - text: "${params.searchQuery}", - orderBy: id orderDirection: desc ${pagination} ${getFilteredServiceDescriptionCondition( - params, - )} - ){ - ${serviceDescriptionQueryFields} - service { - ${serviceQueryFields} - } - } - }`; - return this.graphQlClient.get(query); + return this.graphQlClient.get(searchServices(params)); } public async create( diff --git a/packages/client/src/utils/__tests__/utils.spec.ts b/packages/client/src/utils/__tests__/utils.spec.ts new file mode 100644 index 0000000..9a28ced --- /dev/null +++ b/packages/client/src/utils/__tests__/utils.spec.ts @@ -0,0 +1,27 @@ +import axios from "axios"; +import { DEFAULT_SIGNATURE_VALUE } from "../../constants"; +import { getSignature } from "../signature"; + +jest.mock('axios'); +const mockedAxios = axios as jest.Mocked; + +describe('getSignature', () => { + it('should return default signature value when no signature API url is provided', async () => { + const response = await getSignature('post', []); + expect(response).toEqual(DEFAULT_SIGNATURE_VALUE); + }); + + it('should call signature api url when provided with the method', async () => { + const signatureApiUrl = 'http://www.example.com'; + const method = 'post'; + const args = { test: "data" }; + + // Mock axios.post specifically + mockedAxios.post.mockResolvedValueOnce({ data: { result: JSON.stringify({ foo: 'bar' }) } }); + + const response = await getSignature(method, args, signatureApiUrl); + + expect(axios.post).toHaveBeenCalledWith(signatureApiUrl, { method, args }); + expect(response).toEqual({ foo: 'bar' }); + }); +}); \ No newline at end of file From f4ea15070b07e8f11eff2b31010b12b4aa039613 Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Mon, 20 Nov 2023 00:20:27 +0530 Subject: [PATCH 10/40] removed extra log --- packages/client/src/escrow/__tests__/escrow.spec.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/client/src/escrow/__tests__/escrow.spec.ts b/packages/client/src/escrow/__tests__/escrow.spec.ts index e62da85..aa76a2c 100644 --- a/packages/client/src/escrow/__tests__/escrow.spec.ts +++ b/packages/client/src/escrow/__tests__/escrow.spec.ts @@ -47,8 +47,6 @@ describe('Escrow', () => { checkAllowance: jest.fn(async () => BigInt('10100000000000000001')) }; - console.log('checking escrow erc20: ', escrow.erc20.checkAllowance) - // Act const result = await escrow.approve(serviceId, proposalId, metaEvidenceCid); From 6492b17dd8572e11ec20196588834fa300efd253 Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Mon, 20 Nov 2023 23:20:52 +0530 Subject: [PATCH 11/40] added specs for client main file and reviews --- packages/client/src/__mocks__/clientMocks.ts | 7 +- packages/client/src/__mocks__/fixtures.ts | 13 +++- .../src/__tests__/talentLayerClient.spec.ts | 65 +++++++++++++++++ .../src/reviews/__tests__/reviews.spec.ts | 72 +++++++++++++++++++ packages/client/src/reviews/index.ts | 2 +- .../src/services/__tests__/services.spec.ts | 2 +- 6 files changed, 156 insertions(+), 5 deletions(-) create mode 100644 packages/client/src/__tests__/talentLayerClient.spec.ts create mode 100644 packages/client/src/reviews/__tests__/reviews.spec.ts diff --git a/packages/client/src/__mocks__/clientMocks.ts b/packages/client/src/__mocks__/clientMocks.ts index 9f2be83..7c46e7b 100644 --- a/packages/client/src/__mocks__/clientMocks.ts +++ b/packages/client/src/__mocks__/clientMocks.ts @@ -2,8 +2,9 @@ import { getPaymentsByService, getProtocolAndPlatformsFees } from "../escrow/gra import { getPlatformById, getPlatformsByOwner, getProtocolById } from "../platform/graphql/queries"; import { getMintFees, getPaymentsForUser, getProfileByAddress, getProfileById, getProfiles, getUserTotalGains } from "../profile/graphql"; import { getAllProposalsByServiceId, getAllProposalsByUser, getProposalById } from "../proposals/graphql"; +import { getReviewsByService } from "../reviews/graphql"; import { getOne, getServices, searchServices } from "../services/graphql/queries"; -import { mockGraphQlMintFeesResponse, mockGraphQlProtocolByIdResponse, mockGraphQlUsersResponse, testAddress, testChainId, testGetProfilesResponse, testIpfsHash, testOwnerAddress, testPaymentsByServiceResponse, testPlatformId, testPlatformResponse, testPlatformResponseWithArbitrator, testPlatformsByOwnerResponse, testProposalId, testProposalIdWithDifferentRateToken, testProposalResponse, testProposalResponseWithDifferentRateToken, testProposalsByServiceId, testProposalsByUser, testProtocolAndPlatformResponse, testSearchServiceProps, testSearchServicesResponse, testServiceId, testServiceResponse, testUserId, testUserPaymentsResponse, testUserResponse, testUserTotalGainsResponse } from "./fixtures"; +import { mockGraphQlMintFeesResponse, mockGraphQlProtocolByIdResponse, mockGraphQlUsersResponse, testAddress, testChainId, testGetProfilesResponse, testIpfsHash, testOwnerAddress, testPaymentsByServiceResponse, testPlatformId, testPlatformResponse, testPlatformResponseWithArbitrator, testPlatformsByOwnerResponse, testProposalId, testProposalIdWithDifferentRateToken, testProposalResponse, testProposalResponseWithDifferentRateToken, testProposalsByServiceId, testProposalsByUser, testProtocolAndPlatformResponse, testReviewsByService, testSearchServiceProps, testSearchServicesResponse, testServiceId, testServiceResponse, testUserId, testUserPaymentsResponse, testUserResponse, testUserTotalGainsResponse } from "./fixtures"; export class MockGraphQLClient { get = jest.fn(async (query: string) => { @@ -79,6 +80,10 @@ export class MockGraphQLClient { return testSearchServicesResponse; } + if (query === getReviewsByService(testServiceId)) { + return testReviewsByService; + } + return { data: { "racoon": "bar" } }; }) diff --git a/packages/client/src/__mocks__/fixtures.ts b/packages/client/src/__mocks__/fixtures.ts index 5e961a5..db0a6c0 100644 --- a/packages/client/src/__mocks__/fixtures.ts +++ b/packages/client/src/__mocks__/fixtures.ts @@ -77,7 +77,7 @@ export const testProposalIdWithDifferentRateToken = '12-84'; export const testProposalResponse = { "data": { "proposal": { "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" } } }; export const testProposalResponseWithDifferentRateToken = { "data": { "proposal": { "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": testAddress }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" } } } export const testProtocolAndPlatformResponse = { "data": { "protocols": [{ "protocolEscrowFeeRate": 100 }], "servicePlatform": { "originServiceFeeRate": 0 }, "proposalPlatform": { "originValidatedProposalFeeRate": 0 } } } -export const testServiceId = '12'; +export const testServiceId = '12'; // rest to 12 before comitting export const testAmount = BigInt('1000'); export const testServiceResponse = { "data": { "service": { "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ", "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } } } }; export const testSearchServicesResponse = { data: { "services": [{ "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ", "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } }] } } @@ -106,4 +106,13 @@ export const testSignature = ''; export const testSearchServiceProps: IProps = { serviceStatus: ServiceStatusEnum.Opened } -export const testMetaEvidenceCid = 'testMetaEvidenceCid'; \ No newline at end of file +export const testMetaEvidenceCid = 'testMetaEvidenceCid'; + +export const testReviewDetails = { + content: 'test content', + rating: 1 +} + +export const testReviewsByService = { + data: { "reviews": [{ "id": "2", "rating": "5", "createdAt": "1680027301", "service": { "id": "1", "status": "Finished" }, "to": { "id": "1", "handle": "thomas" }, "description": { "id": "QmRN1ZBFAkSXX34YBd6JrVaSNJWLmt7UVPXvTuXfH2dmUq-1680027301", "content": "Top :)" } }, { "id": "1", "rating": "5", "createdAt": "1680027235", "service": { "id": "1", "status": "Finished" }, "to": { "id": "2", "handle": "migmig" }, "description": { "id": "QmW612hUxvg1SigPA5Y3msuBEuXfLaH3axp22dr1kwCXp8-1680027235", "content": "Perfect!" } }] } +} \ No newline at end of file diff --git a/packages/client/src/__tests__/talentLayerClient.spec.ts b/packages/client/src/__tests__/talentLayerClient.spec.ts new file mode 100644 index 0000000..71bd22e --- /dev/null +++ b/packages/client/src/__tests__/talentLayerClient.spec.ts @@ -0,0 +1,65 @@ + +import { ERC20 } from '../blockchain-bindings/erc20'; +import { Disputes } from '../disputes'; +import { Escrow } from '../escrow'; +import { TalentLayerClient } from '../index'; +import { Platform } from '../platform'; +import { Profile } from '../profile'; +import { Proposal } from '../proposals'; +import { Review } from '../reviews'; +import { Service } from '../services'; +import { testPlatformId } from '../__mocks__/fixtures'; + + +jest.mock('axios') +jest.mock('ipfs-http-client', () => ({ + create: jest.fn().mockImplementation(() => ({ + add: jest.fn().mockResolvedValue({ path: '0xracoon' }), // Mocking the add method of IPFS client + })), +})); + +describe('TalentLayerClient', () => { + let client: any; + + beforeEach(() => { + Object.defineProperty(globalThis, 'window', { + }); + const chainId = 137; + const ipfsConfig = { + clientId: 'abcd', + clientSecret: 'abcde', + baseUrl: 'www.example.com' + } + const viemConfig = {}; + const platformID = testPlatformId; + const signatureApiUrl = 'www.example.com'; + client = new TalentLayerClient({ + chainId: chainId, + ipfsConfig: ipfsConfig, + platformId: testPlatformId, + signatureApiUrl: signatureApiUrl + }) + + + }) + + describe('constructor', () => { + it('should be initialised successfully', async () => { + expect(client).toBeDefined() + + }) + }) + + describe('getters', () => { + it('should return all domain specific getters', async () => { + expect(client.platform).toBeInstanceOf(Platform) + expect(client.erc20).toBeInstanceOf(ERC20) + expect(client.proposal).toBeInstanceOf(Proposal) + expect(client.disputes).toBeInstanceOf(Disputes) + expect(client.service).toBeInstanceOf(Service) + expect(client.profile).toBeInstanceOf(Profile) + expect(client.escrow).toBeInstanceOf(Escrow) + expect(client.review).toBeInstanceOf(Review) + }) + }) +}); \ No newline at end of file diff --git a/packages/client/src/reviews/__tests__/reviews.spec.ts b/packages/client/src/reviews/__tests__/reviews.spec.ts new file mode 100644 index 0000000..7ffaed1 --- /dev/null +++ b/packages/client/src/reviews/__tests__/reviews.spec.ts @@ -0,0 +1,72 @@ + +import { Review } from '..'; +import { getGraphQLConfig } from '../../config'; +import GraphQLClient from '../../graphql'; +import { MockGraphQLClient, MockIPFSClient, MockViemClient } from '../../__mocks__/clientMocks'; +import { testAddress, testAmount, testChainId, testCid, testIpfsHash, testMetaEvidenceCid, testPlatformId, testProposalId, testProposalIdWithDifferentRateToken, testProposalResponse, testProtocolAndPlatformResponse, testReviewDetails, testReviewsByService, testServiceId, testServiceResponse, testUserId } from '../../__mocks__/fixtures'; +import { getReviewsByService } from '../graphql'; +// DO NOT remove this comments - they are needed for local testing +// import { getGraphQLConfig } from "../../config"; +// import GraphQLClient from "../../graphql"; + + +describe('Review', () => { + let review: any; + let mockGraphQLClient: any; + let mockIPFSClient: any; + let mockViemClient: any; + + beforeEach(() => { + mockGraphQLClient = new MockGraphQLClient(); + // DO NOT remove this comments - they are needed for local testing + // mockGraphQLClient = new GraphQLClient(getGraphQLConfig(80001)) + mockIPFSClient = new MockIPFSClient(); + mockViemClient = new MockViemClient(); + review = new Review(mockGraphQLClient, mockIPFSClient, mockViemClient, testPlatformId); + }); + + describe('uploadReviewDataToIpfs', () => { + it('should upload review data object to ipfs', async () => { + // Arrange + const reviewDetails = testReviewDetails; + + // Act + const response = await review.uploadReviewDataToIpfs(reviewDetails); + + // Assert + expect(mockIPFSClient.post).toHaveBeenCalledWith(JSON.stringify(reviewDetails)); + expect(response).toEqual(testIpfsHash); + + }) + }) + + describe('create', () => { + it('should create a review for a service', async () => { + // Arrange + const reviewDetails = testReviewDetails; + + // Act + const response = await review.create(reviewDetails, testServiceId, testUserId); + + // Assert + expect(mockIPFSClient.post).toHaveBeenCalledWith(JSON.stringify(reviewDetails)); + expect(response.cid).toEqual(testIpfsHash); + expect(response.tx).toEqual(testAddress); + }) + }) + + describe('getByService', () => { + it('should return reviews for a service', async () => { + // Arrange + const serviceId = testServiceId; + + // Act + const response = await review.getByService(serviceId); + + // Assert + expect(mockGraphQLClient.get).toHaveBeenCalledWith(getReviewsByService(testServiceId)); + expect(response).toEqual(testReviewsByService.data) + }) + }) + +}); \ No newline at end of file diff --git a/packages/client/src/reviews/index.ts b/packages/client/src/reviews/index.ts index eaab44f..63bf240 100644 --- a/packages/client/src/reviews/index.ts +++ b/packages/client/src/reviews/index.ts @@ -56,7 +56,7 @@ export class Review { throw new Error(Review.CREATE_ERROR); } - + public async getByService(serviceId: string): Promise { const query = getReviewsByService(serviceId); diff --git a/packages/client/src/services/__tests__/services.spec.ts b/packages/client/src/services/__tests__/services.spec.ts index 415e3f0..08673ce 100644 --- a/packages/client/src/services/__tests__/services.spec.ts +++ b/packages/client/src/services/__tests__/services.spec.ts @@ -4,7 +4,7 @@ import { getPlatformById } from '../../platform/graphql/queries'; import { MockGraphQLClient, MockIPFSClient, MockViemClient } from '../../__mocks__/clientMocks'; import { testAddress, testIpfsHash, testPlatformId, testPlatformResponse, testSearchServiceProps, testSearchServicesResponse, testServiceDetails, testServiceId, testServiceResponse, testSignature, testUserId } from '../../__mocks__/fixtures'; -describe('Platform', () => { +describe('Service', () => { let service: Service; let mockGraphQLClient: any; let mockIPFSClient: any; From 680c4263e02ab48116b31bc955bdace9bd2948b8 Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Wed, 22 Nov 2023 21:27:56 +0530 Subject: [PATCH 12/40] added typedoc --- package-lock.json | 78 ++++++++++++++++++++++++++- package.json | 15 +++--- packages/client/package.json | 3 +- packages/client/src/services/index.ts | 35 ++++++++++++ packages/client/tsdoc.json | 6 +++ packages/client/typedoc.json | 16 ++++++ packages/tsconfig/base.json | 6 ++- typedoc.base.json | 4 ++ typedoc.json | 8 +++ 9 files changed, 161 insertions(+), 10 deletions(-) create mode 100644 packages/client/tsdoc.json create mode 100644 packages/client/typedoc.json create mode 100644 typedoc.base.json create mode 100644 typedoc.json diff --git a/package-lock.json b/package-lock.json index 7c4d8f1..ba88001 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,8 @@ "prettier": "^3.0.3", "ts-jest": "^29.1.1", "tsconfig": "*", - "turbo": "latest" + "turbo": "latest", + "typedoc": "0.25.3" } }, "apps/docs": { @@ -4064,6 +4065,12 @@ "node": ">=8" } }, + "node_modules/ansi-sequence-parser": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", + "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==", + "dev": true + }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -10834,6 +10841,12 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -11079,6 +11092,12 @@ "node": ">=12" } }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -11120,6 +11139,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/meow": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz", @@ -13102,6 +13133,18 @@ "node": ">=8" } }, + "node_modules/shiki": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.5.tgz", + "integrity": "sha512-1gCAYOcmCFONmErGTrS1fjzJLA7MGZmKzrBNX7apqSwhyITJg2O102uFzXUeBxNnEkDA9vHIKLyeKq0V083vIw==", + "dev": true, + "dependencies": { + "ansi-sequence-parser": "^1.1.0", + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" + } + }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -14525,6 +14568,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typedoc": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.3.tgz", + "integrity": "sha512-Ow8Bo7uY1Lwy7GTmphRIMEo6IOZ+yYUyrc8n5KXIZg1svpqhZSWgni2ZrDhe+wLosFS8yswowUzljTAV/3jmWw==", + "dev": true, + "dependencies": { + "lunr": "^2.3.9", + "marked": "^4.3.0", + "minimatch": "^9.0.3", + "shiki": "^0.14.1" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x" + } + }, "node_modules/typescript": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", @@ -14793,6 +14857,18 @@ } } }, + "node_modules/vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", + "dev": true + }, + "node_modules/vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", diff --git a/package.json b/package.json index 050aa00..639a0e5 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,17 @@ { "private": true, + "workspaces": [ + "apps/*", + "packages/*" + ], "scripts": { "build": "turbo run build", "dev": "turbo run dev", "lint": "turbo run lint", "format": "prettier --write \"**/*.{ts,tsx,md}\"", - "test": "turbo test" + "test": "turbo test", + "docs": "typedoc", + "docs-all": "npm run docs --workspaces --if-present --verbose" }, "devDependencies": { "@types/jest": "^29.5.8", @@ -14,14 +20,11 @@ "prettier": "^3.0.3", "ts-jest": "^29.1.1", "tsconfig": "*", - "turbo": "latest" + "turbo": "latest", + "typedoc": "0.25.3" }, "name": "talentlayer-sdk", "packageManager": "yarn@1.22.19", - "workspaces": [ - "apps/*", - "packages/*" - ], "dependencies": { "@changesets/cli": "^2.26.2" } diff --git a/packages/client/package.json b/packages/client/package.json index 852880f..5e925dc 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -12,7 +12,8 @@ "prepare": "npm run build", "build": "tsup src/index.ts --format cjs,esm --dts", "dev": "npm run build -- --watch", - "test": "jest --verbose --coverage" + "test": "jest --verbose --coverage", + "docs": "typedoc --out docs" }, "devDependencies": { "@turbo/gen": "^1.10.12", diff --git a/packages/client/src/services/index.ts b/packages/client/src/services/index.ts index e4ff668..0bba930 100644 --- a/packages/client/src/services/index.ts +++ b/packages/client/src/services/index.ts @@ -23,6 +23,9 @@ export interface IService { search(params: IProps): Promise; } +/** + * Class representing Services inside TalentLayer + */ export class Service { graphQlClient: GraphQLClient; ipfsClient: IPFSClient; @@ -45,10 +48,20 @@ export class Service { this.signatureApiUrl = signatureApiUrl; } + /** + * Asynchronously gets the service signature. + * @param {ICreateServiceSignature} args - The arguments to get the service signature. + * @returns {Promise} - A promise that resolves to the service signature. + */ public async getServiceSignature(args: ICreateServiceSignature) { return getSignature('createService', args, this.signatureApiUrl); } + /** + * Asynchronously retrieves a single service by its ID. + * @param {string} id - The ID of the service to retrieve. + * @returns {Promise} - A promise that resolves to the retrieved service. + */ public async getOne(id: string): Promise { const query = getOne(id); @@ -57,6 +70,11 @@ export class Service { return response?.data?.service || {}; } + /** + * Asynchronously uploads service data to IPFS. + * @param {ServiceDetails} serviceData - The service data to upload. + * @returns {Promise} - A promise that resolves to the IPFS address of the uploaded data. + */ public async updloadServiceDataToIpfs(serviceData: ServiceDetails): Promise { if (this.ipfsClient) { return this.ipfsClient.post(JSON.stringify(serviceData)); @@ -65,15 +83,32 @@ export class Service { throw new Error(IPFSClient.IPFS_CLIENT_ERROR); } + /** + * Asynchronously gets multiple services based on provided parameters. + * @param {IProps} params - The parameters to filter the services. + * @returns {Promise} - A promise that resolves to the list of services. + */ public async getServices(params: IProps): Promise { return this.graphQlClient.get(getServices(params)); } + /** + * Asynchronously searches for services based on provided parameters. + * @param {IProps} params - The search parameters. + * @returns {Promise} - A promise that resolves to the search results. + */ public async search(params: IProps): Promise { return this.graphQlClient.get(searchServices(params)); } + /** + * Asynchronously creates a new service. + * @param {ServiceDetails} serviceDetails - The details of the service to create. + * @param {string} userId - The user ID creating the service. + * @param {number} platformId - The platform ID where the service is created. + * @returns {Promise} - A promise that resolves to the transaction response of the service creation. + */ public async create( serviceDetails: ServiceDetails, userId: string, diff --git a/packages/client/tsdoc.json b/packages/client/tsdoc.json new file mode 100644 index 0000000..fda4823 --- /dev/null +++ b/packages/client/tsdoc.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + "extends": [ + "typedoc/tsdoc.json" + ] +} \ No newline at end of file diff --git a/packages/client/typedoc.json b/packages/client/typedoc.json new file mode 100644 index 0000000..0a2ee04 --- /dev/null +++ b/packages/client/typedoc.json @@ -0,0 +1,16 @@ +{ + "tsconfig": "./tsconfig.json", + "extends": [ + "../../typedoc.base.json" + ], + "entryPoints": [ + "src/disputes/index.ts", + "src/escrow/index.ts", + "src/platform/index.ts", + "src/profile/index.ts", + "src/proposals/index.ts", + "src/reviews/index.ts", + "src/services/index.ts", + "src/index.ts" + ] +} \ No newline at end of file diff --git a/packages/tsconfig/base.json b/packages/tsconfig/base.json index 95804de..78e2945 100644 --- a/packages/tsconfig/base.json +++ b/packages/tsconfig/base.json @@ -19,5 +19,7 @@ "strict": true, "strictNullChecks": true }, - "exclude": ["node_modules"] -} + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/typedoc.base.json b/typedoc.base.json new file mode 100644 index 0000000..7c467b8 --- /dev/null +++ b/typedoc.base.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "includeVersion": true +} \ No newline at end of file diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 0000000..743d7a6 --- /dev/null +++ b/typedoc.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "entryPoints": [ + "packages/client" + ], + "entryPointStrategy": "packages", + "name": "TalentLayer SDK Reference", +} \ No newline at end of file From b8c2596850b5b0a82595dfbf0b594ee55506da0a Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Wed, 22 Nov 2023 21:28:03 +0530 Subject: [PATCH 13/40] added docs to gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 8b94e49..602dbe8 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,9 @@ build # client dist +# docs +docs + # misc .DS_Store *.pem From ab423189a7be44a3665d7d40d686f2a22b6030c6 Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Sat, 25 Nov 2023 08:42:23 +0530 Subject: [PATCH 14/40] added a few more tsdoc tags --- packages/client/src/disputes/index.ts | 5 +++++ packages/client/src/escrow/index.ts | 15 +++++++++++++++ packages/client/src/platform/index.ts | 13 +++++++++++++ typedoc.base.json | 10 +++++++++- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/packages/client/src/disputes/index.ts b/packages/client/src/disputes/index.ts index 8e75e4f..d033b1b 100644 --- a/packages/client/src/disputes/index.ts +++ b/packages/client/src/disputes/index.ts @@ -5,6 +5,11 @@ import { getPlatformById } from '../platform/graphql/queries'; import { NetworkEnum, TransactionHash } from '../types'; import { ViemClient } from '../viem'; +/** + * Get arbitration cost. Set price of arbitration + * + * @group TalentLayerClient Modules + */ export class Disputes { wallet: ViemClient; platformID: number; diff --git a/packages/client/src/escrow/index.ts b/packages/client/src/escrow/index.ts index d19d6e4..1fcad81 100644 --- a/packages/client/src/escrow/index.ts +++ b/packages/client/src/escrow/index.ts @@ -8,14 +8,29 @@ import { calculateApprovalAmount } from '../utils/fees'; import { ViemClient } from '../viem'; import { getPaymentsByService, getProtocolAndPlatformsFees } from './graphql/queries'; + + +/** + * Release and reimburse payments using TalentLayer escrow + * + * @group TalentLayerClient Modules + */ export class Escrow { + + /** @hidden */ graphQlClient: GraphQLClient; + /** @hidden */ ipfsClient: IPFSClient; + /** @hidden */ viemClient: ViemClient; + /** @hidden */ platformID: number; + /** @hidden */ chainId: NetworkEnum; + /** @hidden */ erc20: IERC20; + /** @hidden */ constructor( graphQlClient: GraphQLClient, ipfsClient: IPFSClient, diff --git a/packages/client/src/platform/index.ts b/packages/client/src/platform/index.ts index 24c4e39..168aaa2 100644 --- a/packages/client/src/platform/index.ts +++ b/packages/client/src/platform/index.ts @@ -9,13 +9,19 @@ import { getPlatformById, getPlatformsByOwner } from './graphql/queries'; import { Arbitrator, PlatformDetails } from './types'; export class Platform { + /** @hidden */ subgraph: GraphQLClient; + /** @hidden */ wallet: ViemClient; + /** @hidden */ platformID: number; + /** @hidden */ ipfs: IPFSClient; + /** @hidden */ static readonly UPDATE_ERROR = 'unable to update platform details'; + /** @hidden */ constructor( graphQlClient: GraphQLClient, walletClient: ViemClient, @@ -28,6 +34,13 @@ export class Platform { this.ipfs = ipfsClient; } + /** + * Retrieves the details of a specific platform based on the provided ID. + * This method queries the GraphQL client for the platform data and returns the platform details if found. + * + * @param {string} id - The unique identifier of the platform to retrieve. + * @returns {Promise} A promise that resolves to the platform details if found, otherwise null. + */ public async getOne(id: string): Promise { const response = await this.subgraph.get(getPlatformById(id)); diff --git a/typedoc.base.json b/typedoc.base.json index 7c467b8..fa8e790 100644 --- a/typedoc.base.json +++ b/typedoc.base.json @@ -1,4 +1,12 @@ { "$schema": "https://typedoc.org/schema.json", - "includeVersion": true + "includeVersion": true, + "excludeExternals": false, + "excludeInternal": true, + "excludeNotDocumented": false, + "excludePrivate": true, + "excludeProtected": true, + "disableSources": true, + "gitRevision": "develop", + "hideGenerator": true } \ No newline at end of file From cd4314d94fca217130d7e7a3dc7c7a94ae7267fc Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Sat, 25 Nov 2023 16:43:38 +0530 Subject: [PATCH 15/40] added docs for all the sub-domains --- packages/client/src/disputes/index.ts | 15 ++++- packages/client/src/index.ts | 11 ++-- packages/client/src/platform/index.ts | 78 +++++++++++++++++++++++--- packages/client/src/profile/index.ts | 57 ++++++++++++++++++- packages/client/src/proposals/index.ts | 56 ++++++++++++++++++ packages/client/src/reviews/index.ts | 24 ++++++++ packages/client/src/services/index.ts | 6 ++ packages/client/src/types/index.ts | 7 +++ 8 files changed, 238 insertions(+), 16 deletions(-) diff --git a/packages/client/src/disputes/index.ts b/packages/client/src/disputes/index.ts index d033b1b..6323c33 100644 --- a/packages/client/src/disputes/index.ts +++ b/packages/client/src/disputes/index.ts @@ -1,8 +1,8 @@ -import { parseEther, toHex, zeroAddress } from 'viem'; +import { Hash, parseEther, toHex, zeroAddress } from 'viem'; import { getChainConfig } from '../config'; import GraphQLClient from '../graphql'; import { getPlatformById } from '../platform/graphql/queries'; -import { NetworkEnum, TransactionHash } from '../types'; +import { NetworkEnum } from '../types'; import { ViemClient } from '../viem'; /** @@ -27,6 +27,10 @@ export class Disputes { this.chainId = chainId; } + /** + * getArbitrationCost - Retrieves the current cost of arbitration. This function is useful for understanding the financial implications of initiating an arbitration process. + * @returns {Promise} - Returns a Promise that resolves to the arbitration cost, typically in a numerical or string format representing the cost value. + */ public async getArbitrationCost(): Promise { const platformResponse = await this.subgraph.get(getPlatformById(this.platformID.toString())); @@ -57,7 +61,12 @@ export class Disputes { }); } - public async setPrice(value: number | string): Promise { + /** + * setPrice - Sets the price of arbitration. This function allows for modifying the arbitration cost for the current platform + * @param {number | string} value - The new price value for arbitration, which can be specified as a number or a string representing the price. + * @returns {Promise} - A promise that resolves to the transaction hash of the set operation. + */ + public async setPrice(value: number | string): Promise { const transformedPrice = parseEther(value.toString()); console.log('SDK: setting arbitration price'); const tx = await this.wallet.writeContract('talentLayerArbitrator', 'setArbitrationPrice', [ diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index 297ece0..9918b75 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -22,17 +22,20 @@ import { Review } from './reviews'; * Main client for interacting with the TalentLayer protocol. */ export class TalentLayerClient { + /** @hidden */ graphQlClient: GraphQLClient; + /** @hidden */ ipfsClient: IPFSClient; + /** @hidden */ viemClient: ViemClient; + /** @hidden */ platformID: number; + /** @hidden */ chainId: NetworkEnum; + /** @hidden */ signatureApiUrl?: string; - /** - * Initializes a new instance of the TalentLayerClient. - * @param {TalentLayerClientConfig} config - Configuration options for the client. - */ + /** @hidden */ constructor(config: TalentLayerClientConfig) { console.log('SDK: client initialising', config); this.platformID = config.platformId; diff --git a/packages/client/src/platform/index.ts b/packages/client/src/platform/index.ts index 168aaa2..8cbf6d3 100644 --- a/packages/client/src/platform/index.ts +++ b/packages/client/src/platform/index.ts @@ -1,9 +1,9 @@ -import { parseEther, zeroAddress } from 'viem'; +import { Hash, parseEther, zeroAddress } from 'viem'; import { getChainConfig } from '../config'; import { FEE_RATE_DIVIDER } from '../constants'; import GraphQLClient from '../graphql'; import IPFSClient from '../ipfs'; -import { ClientTransactionResponse, NetworkEnum, TransactionHash } from '../types'; +import { ClientTransactionResponse, NetworkEnum } from '../types'; import { ViemClient } from '../viem'; import { getPlatformById, getPlatformsByOwner } from './graphql/queries'; import { Arbitrator, PlatformDetails } from './types'; @@ -51,10 +51,22 @@ export class Platform { return null; } + /** + * Uploads platform details to IPFS and returns the corresponding CID. + * + * @param {PlatformDetails} data - The platform details to be uploaded. + * @returns {Promise} A promise that resolves to the CID of the uploaded data. + */ public async upload(data: PlatformDetails): Promise { return this.ipfs.post(JSON.stringify(data)); } + /** + * Fetches platforms owned by a specific address. + * + * @param {string} address - The wallet address of the platform owner. + * @returns {Promise} A promise that resolves to an array of platforms owned by the address, or an empty array if none. + */ public async getByOwner(address: `0x${string}`): Promise { const response = await this.subgraph.get(getPlatformsByOwner(address)); @@ -65,6 +77,12 @@ export class Platform { return []; } + /** + * Updates the platform details on the blockchain using the provided data. + * + * @param {PlatformDetails} data - The new platform details to be updated. + * @returns {Promise} A promise that resolves to the transaction response of the update operation. + */ public async update(data: PlatformDetails): Promise { console.log('SDK: update platform details'); const cid = await this.upload(data); @@ -81,7 +99,13 @@ export class Platform { return { cid, tx }; } - public async setFeeTimeout(timeout: number): Promise { + /** + * Sets the fee timeout for the platform. + * + * @param {number} timeout - The timeout value in seconds. + * @returns {Promise} A promise that resolves to the transaction hash of the update operation. + */ + public async setFeeTimeout(timeout: number): Promise { const tx = await this.wallet.writeContract( 'talentLayerPlatformId', 'updateArbitrationFeeTimeout', @@ -91,6 +115,12 @@ export class Platform { return tx; } + /** + * Retrieves a list of available arbitrators for a given chain ID. + * + * @param {NetworkEnum} chainId - The blockchain network chain ID. + * @returns {Arbitrator[]} An array of arbitrator objects available for the specified chain. + */ public getArbitrators(chainId: NetworkEnum): Arbitrator[] { const chainConfig = getChainConfig(chainId); const contract = chainConfig.contracts['talentLayerArbitrator']; @@ -102,7 +132,14 @@ export class Platform { return allowedArbitrators; } - public async updateArbitrator(address: `0x${string}`): Promise { + /** + * Updates the arbitrator address for the platform. + * Throws an error if the provided address is not an allowed arbitrator. + * + * @param {Hash} address - The new arbitrator's address. + * @returns {Promise} A promise that resolves to the transaction hash of the update operation. + */ + public async updateArbitrator(address: Hash): Promise { const allowedArbitrators: Arbitrator[] = this.getArbitrators(this.wallet.chainId); const allowedArbitratorAddresses = allowedArbitrators.map((_arbitrator: Arbitrator) => @@ -123,7 +160,14 @@ export class Platform { } // Fee functions - public async updateOriginServiceFeeRate(value: number): Promise { + + /** + * Updates the service fee rate for origin services on the platform. + * + * @param {number} value - The new fee rate as a percentage ( if you want to set the fees to 5%, pass in 5). + * @returns {Promise} A promise that resolves to the transaction hash of the update operation. + */ + public async updateOriginServiceFeeRate(value: number): Promise { const transformedFeeRate = Math.round((Number(value) * FEE_RATE_DIVIDER) / 100); console.log('SDK: transformedFeeRate', transformedFeeRate, this.platformID); @@ -136,7 +180,13 @@ export class Platform { return tx; } - public async updateOriginValidatedProposalFeeRate(value: number): Promise { + /** + * Updates the fee rate for validated proposals + * + * @param {number} value - The new fee rate as a percentage ( if you want to set the fees to 5%, pass in 5). + * @returns {Promise} A promise that resolves to the transaction hash of the update operation. + */ + public async updateOriginValidatedProposalFeeRate(value: number): Promise { const transformedFeeRate = Math.round((Number(value) * FEE_RATE_DIVIDER) / 100); console.log('SDK: transformedFeeRate', transformedFeeRate, this.platformID); @@ -149,7 +199,13 @@ export class Platform { return tx; } - public async updateServicePostingFee(value: number): Promise { + /** + * Updates the posting fee for services on the platform. + * + * @param {number} value - The new fee rate. + * @returns {Promise} A promise that resolves to the transaction hash of the update operation. + */ + public async updateServicePostingFee(value: number): Promise { const transformedFeeRate = parseEther(value.toString()); console.log('SDK: transformedFeeRate', transformedFeeRate, this.platformID); @@ -161,7 +217,13 @@ export class Platform { return tx; } - public async updateProposalPostingFee(value: number): Promise { + /** + * Updates the posting fee for proposals on the platform. + * + * @param {number} value - The new fee rate. + * @returns {Promise} A promise that resolves to the transaction hash of the update operation. + */ + public async updateProposalPostingFee(value: number): Promise { const transformedFeeRate = parseEther(value.toString()); console.log('SDK: updateProposalPostingFee', transformedFeeRate); diff --git a/packages/client/src/profile/index.ts b/packages/client/src/profile/index.ts index 672af93..db66bb5 100644 --- a/packages/client/src/profile/index.ts +++ b/packages/client/src/profile/index.ts @@ -8,14 +8,21 @@ import { getMintFees, getPaymentsForUser, getProfileByAddress, getProfileById, g import { TalentLayerProfile } from './types'; export class Profile { + /** @hidden */ graphQlClient: GraphQLClient; + /** @hidden */ ipfsClient: IPFSClient; + /** @hidden */ viemClient: ViemClient; + /** @hidden */ platformId: number; + /** @hidden */ static CREATE_ERROR = 'unable to create profile'; + /** @hidden */ static UPDATE_ERROR = 'unable to update profile'; + /** @hidden */ constructor( graphQlClient: GraphQLClient, ipfsClient: IPFSClient, @@ -28,6 +35,11 @@ export class Profile { this.viemClient = viemClient; } + /** + * getByAddress - Retrieves a user's profile based on their address. + * @param {Hash} address - The address of the user whose profile is being requested. + * @returns {Promise} - A promise that resolves to the user's profile data, or null if no profile is found. + */ public async getByAddress(address: Hash): Promise { const response = await this.graphQlClient.get(getProfileByAddress(address)); @@ -38,6 +50,11 @@ export class Profile { return null; } + /** + * getById - Fetches a user's profile using their user ID. This is useful for retrieving profile information when the user ID is known, instead of the address + * @param {string} userId - The id of the user whose profile is to be retrieved. + * @returns {Promise} - A promise that resolves to the user's profile data, or null if the profile does not exist. + */ public async getById(userId: string): Promise { const query = getProfileById(userId); @@ -46,10 +63,21 @@ export class Profile { return response?.data?.user || null; } + /** + * upload - Uploads profile data to IPFS and returns the resulting CID. + * @param {TalentLayerProfile} profileData - The profile data to be uploaded. + * @returns {Promise} - A promise that resolves to the Content Identifier (CID) of the uploaded data on IPFS. + */ public async upload(profileData: TalentLayerProfile): Promise { return this.ipfsClient.post(JSON.stringify(profileData)); } + /** + * update - Updates the profile data of a user. This involves uploading new profile data to IPFS and writing the update transaction to the contract. + * @param {TalentLayerProfile} profileData - The new profile data to be updated. + * @param {string} userId - The unique identifier of the user whose profile is being updated. + * @returns {Promise} - A promise that resolves to the transaction response, including the CID and transaction hash. + */ public async update( profileData: TalentLayerProfile, userId: string, @@ -69,7 +97,12 @@ export class Profile { throw new Error(Profile.UPDATE_ERROR); } - public async create(handle: string): Promise { + /** + * create - Creates a new user profile by minting it on the TalentLayerId contract. This function is typically called when a new user registers and a profile needs to be created in the system. + * @param {string} handle - The user handle or username for the new profile. + * @returns {Promise} - A promise that resolves to the transaction hash once the profile creation transaction is completed. + */ + public async create(handle: string): Promise { const proposolResponse = await this.graphQlClient.get(getProtocolById(1)); const protocol = proposolResponse?.data?.protocol; @@ -93,6 +126,11 @@ export class Profile { ); } + /** + * getBy - Retrieves profiles based on specified search criteria. This function is useful for fetching multiple profiles, for instance, when implementing search functionality. + * @param {{ numberPerPage?: number; offset?: number; searchQuery?: string; }} params - The search parameters including pagination and search query. + * @returns {Promise} - A promise that resolves to the list of profiles matching the search criteria. + */ public async getBy(params: { numberPerPage?: number; offset?: number; @@ -103,6 +141,11 @@ export class Profile { return this.graphQlClient.get(query); } + /** + * getTotalGains - Retrieves the total earnings of the user + * @param {string} userId - The unique identifier of the user whose earnings are being queried. + * @returns {Promise} - A promise that resolves to the total earnings of the user. + */ public async getTotalGains(userId: string): Promise { const query = getUserTotalGains(userId); @@ -111,6 +154,14 @@ export class Profile { return response?.data?.user?.totalGains || null; } + /** + * getPayments - Fetches the payments received by the user + * @param {string} userId - The user's unique identifier. + * @param {number} [numberPerPage] - The number of payment records per page for pagination. + * @param {number} [offset] - The offset for pagination. + * @param {string} [startDate] - The start date for filtering the payment history. + * @returns {Promise} - A promise that resolves to the user's payment history. + */ public async getPayments( userId: string, numberPerPage?: number, @@ -125,6 +176,10 @@ export class Profile { return response?.data?.payments || null } + /** + * getMintFees - Retrieves the current profile minting fees for the TalentLayer protocol + * @returns {Promise} - A promise that resolves to the minting fees data. Returns null if no data is found or in case of an error. + */ public async getMintFees(): Promise { const query = getMintFees(); diff --git a/packages/client/src/proposals/index.ts b/packages/client/src/proposals/index.ts index f028b72..2f8a366 100644 --- a/packages/client/src/proposals/index.ts +++ b/packages/client/src/proposals/index.ts @@ -7,13 +7,22 @@ import { ViemClient } from '../viem'; import { getAllProposalsByServiceId, getAllProposalsByUser, getProposalById } from './graphql'; import { CreateProposalArgs, ProposalDetails } from './types'; +/** + * The sub module that deals with proposals associated to services on TalentLayer + */ export class Proposal { + /** @hidden */ graphQlClient: GraphQLClient; + /** @hidden */ ipfsClient: IPFSClient; + /** @hidden */ viemClient: ViemClient; + /** @hidden */ platformID: number; + /** @hidden */ signatureApiUrl?: string; + /** @hidden */ constructor( graphQlClient: GraphQLClient, ipfsClient: IPFSClient, @@ -29,6 +38,11 @@ export class Proposal { this.signatureApiUrl = signatureApiUrl; } + /** + * Retrieves a specific proposal by its ID. + * @param {string} proposalId - The unique identifier of the proposal. + * @returns {Promise} - A promise that resolves to the details of the proposal. + */ public async getOne(proposalId: string): Promise { const query = getProposalById(proposalId); @@ -40,6 +54,11 @@ export class Proposal { return null; } + /** + * Fetches all proposals associated with a specific service ID. + * @param {string} serviceId - The unique identifier of the service. + * @returns {Promise} - A promise that resolves to a list of proposals related to the service. + */ public async getByServiceId(serviceId: string): Promise { const query = getAllProposalsByServiceId(serviceId) @@ -48,6 +67,11 @@ export class Proposal { return response?.data?.proposals || null } + /** + * Retrieves all proposals created by a specific user ID. + * @param {string} userId - The unique identifier of the user. + * @returns {Promise} - A promise that resolves to a list of proposals related to the user. + */ public async getByUser(userId: string): Promise { const query = getAllProposalsByUser(userId) @@ -56,14 +80,35 @@ export class Proposal { return response?.data?.proposals || null } + /** + * Generates a signature for a proposal creation operation. + * @param {CreateProposalArgs} args - The arguments required for creating the proposal signature. + * @returns {Promise} - A promise that resolves to the generated signature string. + */ + public async getSignature(args: CreateProposalArgs): Promise { return getSignature('createProposal', args, this.signatureApiUrl); } + /** + * Uploads proposal details to IPFS and returns the CID. + * @param {ProposalDetails} proposalDetails - The details of the proposal to be uploaded. + * @returns {Promise} - A promise that resolves to the CID of the uploaded proposal data. + */ public async upload(proposalDetails: ProposalDetails): Promise { return this.ipfsClient.post(JSON.stringify(proposalDetails)); } + /** + * Creates a new proposal with the given details. + * @param {ProposalDetails} proposalDetails - The details of the proposal to be created. + * @param {string} userId - The user ID of the proposal creator. + * @param {string} serviceId - The ID of the service for which the proposal is being created + * @param {string} rateToken - The address of the token used for setting the rate. + * @param {string} rateAmount - The amount/rate for which the proposal is being created + * @param {string} expirationDate - The expiration date of the proposal. + * @returns {Promise} - A promise that resolves to the transaction response for the proposal creation {cid and txHash}. + */ public async create( proposalDetails: ProposalDetails, userId: string, @@ -104,6 +149,17 @@ export class Proposal { throw new Error('Unable to update propsal service'); } + /** + * Updates an existing proposal with new details. + * This method is used to modify the attributes of a proposal, such as rate, expiration date, or other proposal-related details. + * @param {ProposalDetails} proposalDetails - The updated details of the proposal. + * @param {string} userId - The user ID of the individual updating the proposal. + * @param {string} serviceId - The service ID associated with the proposal. + * @param {string} rateToken - The token used for setting the new rate. + * @param {string} rateAmount - The new amount/rate associated with the proposal. + * @param {string} expirationDate - The new expiration date of the proposal. + * @returns {Promise} - A promise that resolves to the transaction response for the proposal update. Includes the CID of the updated proposal data and the transaction hash. + */ public async update( proposalDetails: ProposalDetails, userId: string, diff --git a/packages/client/src/reviews/index.ts b/packages/client/src/reviews/index.ts index 63bf240..1898b86 100644 --- a/packages/client/src/reviews/index.ts +++ b/packages/client/src/reviews/index.ts @@ -6,13 +6,19 @@ import { getReviewsByService } from './graphql'; import { ReviewDetails } from './types'; export class Review { + /** @hidden */ graphQlClient: GraphQLClient; + /** @hidden */ ipfsClient: IPFSClient; + /** @hidden */ viemClient: ViemClient; + /** @hidden */ platformId: number; + /** @hidden */ static CREATE_ERROR = 'unable to submit review'; + /** @hidden */ constructor( graphQlClient: GraphQLClient, ipfsClient: IPFSClient, @@ -27,6 +33,11 @@ export class Review { this.viemClient = viemClient; } + /** + * Uploads review data to IPFS and returns the CID. This function is called during review creation + * @param {ReviewDetails} data - The review data to be uploaded. + * @returns {Promise} - A promise that resolves to the CID of the uploaded review data. + */ public async uploadReviewDataToIpfs(data: ReviewDetails): Promise { if (this.ipfsClient) { return this.ipfsClient.post(JSON.stringify(data)); @@ -35,6 +46,14 @@ export class Review { throw new Error(IPFSClient.IPFS_CLIENT_ERROR); } + /** + * Creates a new review with the given details for a service. + * @param {ReviewDetails} data - The details of the review to be created. + * @param {string} serviceId - The service ID associated with the review. + * @param {string} userId - The user ID of the user creating the review. + * @returns {Promise} - A promise that resolves to the transaction response for the review creation. Includes the CID of the review data and the transaction hash. + * @throws {Error} - Throws an error if unable to submit the review. + */ public async create( data: ReviewDetails, serviceId: string, @@ -57,6 +76,11 @@ export class Review { throw new Error(Review.CREATE_ERROR); } + /** + * Retrieves all reviews associated with a specific service ID. + * @param {string} serviceId - The unique identifier of the service. + * @returns {Promise} - A promise that resolves to the reviews related to the specified service. + */ public async getByService(serviceId: string): Promise { const query = getReviewsByService(serviceId); diff --git a/packages/client/src/services/index.ts b/packages/client/src/services/index.ts index 0bba930..ca2581d 100644 --- a/packages/client/src/services/index.ts +++ b/packages/client/src/services/index.ts @@ -27,12 +27,18 @@ export interface IService { * Class representing Services inside TalentLayer */ export class Service { + /** @hidden */ graphQlClient: GraphQLClient; + /** @hidden */ ipfsClient: IPFSClient; + /** @hidden */ viemClient: ViemClient; + /** @hidden */ platformID: number; + /** @hidden */ signatureApiUrl?: string; + /** @hidden */ constructor( graphQlClient: GraphQLClient, ipfsClient: IPFSClient, diff --git a/packages/client/src/types/index.ts b/packages/client/src/types/index.ts index 53b546a..c61ea71 100644 --- a/packages/client/src/types/index.ts +++ b/packages/client/src/types/index.ts @@ -54,6 +54,13 @@ export type TalentLayerClientConfig = { signatureApiUrl?: string; }; +/** + * Represents the response of a transaction made through the client. + * This type is typically used to encapsulate details of blockchain transactions initiated by the client. + * + * @property {Hash} tx - The transaction hash that uniquely identifies the transaction on the blockchain. + * @property {string} cid - The Content Identifier (CID) referring to the location of the transaction-related data stored on IPFS. + */ export type ClientTransactionResponse = { tx: Hash; cid: string; From 9feb6abd73de114bc07b639d07a0b3c53e44a6fc Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Wed, 29 Nov 2023 09:30:26 +0000 Subject: [PATCH 16/40] Updated createService function Added updateService function --- packages/client/src/services/index.ts | 39 ++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/packages/client/src/services/index.ts b/packages/client/src/services/index.ts index e4ff668..094f3f4 100644 --- a/packages/client/src/services/index.ts +++ b/packages/client/src/services/index.ts @@ -17,6 +17,14 @@ export interface IService { serviceDetails: ServiceDetails, userId: string, platformId: number, + token: string, + referralAmount?: number, + ): Promise; + update( + serviceDetails: ServiceDetails, + userId: string, + serviceId: number, + referralAmount?: number, ): Promise; updloadServiceDataToIpfs(serviceData: ServiceDetails): Promise; getServices(params: IProps): Promise; @@ -78,6 +86,8 @@ export class Service { serviceDetails: ServiceDetails, userId: string, platformId: number, + token: string, + referralAmount?: number, ): Promise { const platformDetailsResponse = await this.graphQlClient.get( getPlatformById(this.platformID.toString()), @@ -92,10 +102,13 @@ export class Service { cid, }); + // Referral amount is optional and can be 0 + const refAmount = referralAmount ? BigInt(referralAmount) : BigInt(0); + const tx = await this.viemClient.writeContract( 'talentLayerService', 'createService', - [userId, platformId, cid, signature], + [userId, platformId, cid, signature, token, refAmount], servicePostingFee, ); @@ -105,4 +118,28 @@ export class Service { throw new Error('Unable to create service'); } + + public async update( + serviceDetails: ServiceDetails, + userId: string, + serviceId: number, + referralAmount?: number, + ): Promise { + const cid = await this.updloadServiceDataToIpfs(serviceDetails); + + // Referral amount is optional and can be 0 + const refAmount = referralAmount ? BigInt(referralAmount) : BigInt(0); + + const tx = await this.viemClient.writeContract( + 'talentLayerService', + 'updateService', + [userId, serviceId, refAmount, cid] + ); + + if (cid && tx) { + return { cid, tx }; + } + + throw new Error('Unable to update service'); + } } From e0f5ac4f89d0c7a6fdd5dd1587c33773832df43d Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Wed, 29 Nov 2023 09:50:05 +0000 Subject: [PATCH 17/40] Refactored Service Type --- packages/client/src/index.ts | 3 +- packages/client/src/services/index.ts | 34 +++------------------ packages/client/src/services/types/index.ts | 21 +++++++++++++ 3 files changed, 27 insertions(+), 31 deletions(-) diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index 297ece0..66ebdbe 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -14,9 +14,10 @@ import { Profile } from './profile'; import { IProfile } from './profile/types'; import { Escrow } from './escrow'; import { IEscrow } from './escrow/types'; -import { IService, Service } from './services'; +import { Service } from './services'; import { IReview } from './reviews/types'; import { Review } from './reviews'; +import { IService } from "./services/types"; /** * Main client for interacting with the TalentLayer protocol. diff --git a/packages/client/src/services/index.ts b/packages/client/src/services/index.ts index 094f3f4..edf7d17 100644 --- a/packages/client/src/services/index.ts +++ b/packages/client/src/services/index.ts @@ -11,26 +11,6 @@ import { } from './graphql/queries'; import { ICreateServiceSignature, IProps, ServiceDetails } from './types'; -export interface IService { - getOne(id: string): Promise; - create( - serviceDetails: ServiceDetails, - userId: string, - platformId: number, - token: string, - referralAmount?: number, - ): Promise; - update( - serviceDetails: ServiceDetails, - userId: string, - serviceId: number, - referralAmount?: number, - ): Promise; - updloadServiceDataToIpfs(serviceData: ServiceDetails): Promise; - getServices(params: IProps): Promise; - search(params: IProps): Promise; -} - export class Service { graphQlClient: GraphQLClient; ipfsClient: IPFSClient; @@ -87,7 +67,7 @@ export class Service { userId: string, platformId: number, token: string, - referralAmount?: number, + referralAmount: number = 0, ): Promise { const platformDetailsResponse = await this.graphQlClient.get( getPlatformById(this.platformID.toString()), @@ -102,13 +82,10 @@ export class Service { cid, }); - // Referral amount is optional and can be 0 - const refAmount = referralAmount ? BigInt(referralAmount) : BigInt(0); - const tx = await this.viemClient.writeContract( 'talentLayerService', 'createService', - [userId, platformId, cid, signature, token, refAmount], + [userId, platformId, cid, signature, token, referralAmount], servicePostingFee, ); @@ -123,17 +100,14 @@ export class Service { serviceDetails: ServiceDetails, userId: string, serviceId: number, - referralAmount?: number, + referralAmount: number = 0, ): Promise { const cid = await this.updloadServiceDataToIpfs(serviceDetails); - // Referral amount is optional and can be 0 - const refAmount = referralAmount ? BigInt(referralAmount) : BigInt(0); - const tx = await this.viemClient.writeContract( 'talentLayerService', 'updateService', - [userId, serviceId, refAmount, cid] + [userId, serviceId, referralAmount, cid] ); if (cid && tx) { diff --git a/packages/client/src/services/types/index.ts b/packages/client/src/services/types/index.ts index 3fa82b8..cd0bbe6 100644 --- a/packages/client/src/services/types/index.ts +++ b/packages/client/src/services/types/index.ts @@ -1,4 +1,25 @@ import { ServiceStatusEnum } from '../enums'; +import {ClientTransactionResponse} from "../../types"; + +export interface IService { + getOne(id: string): Promise; + create( + serviceDetails: ServiceDetails, + userId: string, + platformId: number, + token: string, + referralAmount?: number, + ): Promise; + update( + serviceDetails: ServiceDetails, + userId: string, + serviceId: number, + referralAmount?: number, + ): Promise; + updloadServiceDataToIpfs(serviceData: ServiceDetails): Promise; + getServices(params: IProps): Promise; + search(params: IProps): Promise; +} export type ServiceDetails = { title: string; From f224630a7537e93675b551d11b0e06e83f8b7450 Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Wed, 29 Nov 2023 09:50:54 +0000 Subject: [PATCH 18/40] Updated Proposal functions & types --- packages/client/src/proposals/index.ts | 12 +++---- packages/client/src/proposals/types/index.ts | 38 +++++++++----------- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/packages/client/src/proposals/index.ts b/packages/client/src/proposals/index.ts index f028b72..76f312f 100644 --- a/packages/client/src/proposals/index.ts +++ b/packages/client/src/proposals/index.ts @@ -68,9 +68,9 @@ export class Proposal { proposalDetails: ProposalDetails, userId: string, serviceId: string, - rateToken: string, rateAmount: string, expirationDate: string, + referrerId: string = '0', ): Promise { const cid = await this.upload(proposalDetails); const signature = await this.getSignature({ @@ -93,7 +93,7 @@ export class Proposal { const tx = await this.viemClient.writeContract( 'talentLayerService', 'createProposal', - [userId, serviceId, rateToken, rateAmount, this.platformID, cid, expirationDate, signature], + [userId, serviceId, rateAmount, this.platformID, cid, expirationDate, signature, referrerId], proposalPostingFees, ); @@ -101,31 +101,31 @@ export class Proposal { return { cid, tx }; } - throw new Error('Unable to update propsal service'); + throw new Error('Unable to create the proposal'); } public async update( proposalDetails: ProposalDetails, userId: string, serviceId: string, - rateToken: string, rateAmount: string, expirationDate: string, + referrerId: string = '0', ): Promise { const cid = await this.upload(proposalDetails); const tx = await this.viemClient.writeContract('talentLayerService', 'updateProposal', [ userId, serviceId, - rateToken, rateAmount, cid, expirationDate, + referrerId, ]); if (cid && tx) { return { cid, tx }; } - throw new Error('Unable to update propsal service'); + throw new Error('Unable to update the proposal'); } } diff --git a/packages/client/src/proposals/types/index.ts b/packages/client/src/proposals/types/index.ts index d0f8519..23af277 100644 --- a/packages/client/src/proposals/types/index.ts +++ b/packages/client/src/proposals/types/index.ts @@ -13,31 +13,25 @@ export interface CreateProposalArgs { } export interface IProposal { + getOne(id: string): Promise; + getByServiceId(id: string): Promise; + getByUser(id: string): Promise; getSignature(args: CreateProposalArgs): Promise; - - getOne(proposalId: string): Promise; - - getByServiceId(serviceId: string): Promise; - - getByUser(userId: string): Promise; - + upload(proposalDetails: ProposalDetails): Promise; create( - proposalDetails: ProposalDetails, - userId: string, - serviceId: string, - rateToken: string, - rateAmount: string, - expirationDate: string + proposalDetails: ProposalDetails, + userId: string, + serviceId: string, + rateAmount: string, + expirationDate: string, + referrerId?: string, ): Promise; - update( - proposalDetails: ProposalDetails, - userId: string, - serviceId: string, - rateToken: string, - rateAmount: string, - expirationDate: string + proposalDetails: ProposalDetails, + userId: string, + serviceId: string, + rateAmount: string, + expirationDate: string, + referrerId?: string, ): Promise; - - upload(proposalDetails: ProposalDetails): Promise; } From a081b4c14ad9763c31417aeedc9a840c60725f16 Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Wed, 29 Nov 2023 10:04:54 +0000 Subject: [PATCH 19/40] Updated Escrow functions & types --- packages/client/src/escrow/index.ts | 20 ++++++++++++++++---- packages/client/src/escrow/types/index.ts | 2 ++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/client/src/escrow/index.ts b/packages/client/src/escrow/index.ts index d19d6e4..eed7a68 100644 --- a/packages/client/src/escrow/index.ts +++ b/packages/client/src/escrow/index.ts @@ -7,8 +7,9 @@ import { ClientTransactionResponse, NetworkEnum, RateToken } from '../types'; import { calculateApprovalAmount } from '../utils/fees'; import { ViemClient } from '../viem'; import { getPaymentsByService, getProtocolAndPlatformsFees } from './graphql/queries'; +import { IEscrow } from "./types"; -export class Escrow { +export class Escrow implements IEscrow { graphQlClient: GraphQLClient; ipfsClient: IPFSClient; viemClient: ViemClient; @@ -178,15 +179,20 @@ export class Escrow { throw new Error('Transaction Id not found for service'); } - const tx = await this.viemClient.writeContract('talentLayerEscrow', 'reimburse', [ + return await this.viemClient.writeContract('talentLayerEscrow', 'reimburse', [ userId, parseInt(transactionId), amount.toString(), ]); - - return tx; } + public async claimReferralBalance(referrerId: string, tokenAddress: string): Promise { + return await this.viemClient.writeContract('talentLayerEscrow', 'claimReferralBalance', [ + referrerId, + tokenAddress, + ]); + } + public async getProtocolAndPlatformsFees( originServicePlatformId: string, originValidatedProposalPlatformId: string, @@ -206,4 +212,10 @@ export class Escrow { return response?.data?.payments || null } + public async getClaimableReferralBalance(address: string): Promise { + return await this.viemClient.readContract('talentLayerEscrow', 'getClaimableReferralBalance', [ + address, + ]); + } + } diff --git a/packages/client/src/escrow/types/index.ts b/packages/client/src/escrow/types/index.ts index 9e74b15..52b6c98 100644 --- a/packages/client/src/escrow/types/index.ts +++ b/packages/client/src/escrow/types/index.ts @@ -8,9 +8,11 @@ export interface IEscrow { ): Promise; release(serviceId: string, amount: bigint, userId: number): Promise; reimburse(serviceId: string, amount: bigint, userId: number): Promise; + claimReferralBalance(referrerId: string, tokenAddress: string): Promise; getProtocolAndPlatformsFees( originServicePlatformId: string, originValidatedProposalPlatformId: string, ): Promise; getByService(serviceId: string, paymentType?: string): Promise; + getClaimableReferralBalance(address: string): Promise; } From 4cd9ca5e3d8e91d3d66f1fc0cab9dec9868f2f5e Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Wed, 29 Nov 2023 10:06:49 +0000 Subject: [PATCH 20/40] Added interface implementations in Proposal & Service --- packages/client/src/proposals/index.ts | 4 ++-- packages/client/src/services/index.ts | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/client/src/proposals/index.ts b/packages/client/src/proposals/index.ts index 76f312f..23c2c85 100644 --- a/packages/client/src/proposals/index.ts +++ b/packages/client/src/proposals/index.ts @@ -5,9 +5,9 @@ import { ClientTransactionResponse } from '../types'; import { getSignature } from '../utils/signature'; import { ViemClient } from '../viem'; import { getAllProposalsByServiceId, getAllProposalsByUser, getProposalById } from './graphql'; -import { CreateProposalArgs, ProposalDetails } from './types'; +import { CreateProposalArgs, IProposal, ProposalDetails } from './types'; -export class Proposal { +export class Proposal implements IProposal { graphQlClient: GraphQLClient; ipfsClient: IPFSClient; viemClient: ViemClient; diff --git a/packages/client/src/services/index.ts b/packages/client/src/services/index.ts index edf7d17..abd8ed6 100644 --- a/packages/client/src/services/index.ts +++ b/packages/client/src/services/index.ts @@ -9,9 +9,14 @@ import { getServices, searchServices, } from './graphql/queries'; -import { ICreateServiceSignature, IProps, ServiceDetails } from './types'; +import { + ICreateServiceSignature, + IProps, + IService, + ServiceDetails, +} from './types'; -export class Service { +export class Service implements IService { graphQlClient: GraphQLClient; ipfsClient: IPFSClient; viemClient: ViemClient; From 0ffa0f5d6e4a699bf44b141d8b83820c3b3cbbac Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Wed, 29 Nov 2023 16:08:11 +0000 Subject: [PATCH 21/40] Fixed typo --- packages/client/src/profile/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/client/src/profile/index.ts b/packages/client/src/profile/index.ts index 672af93..4a225d5 100644 --- a/packages/client/src/profile/index.ts +++ b/packages/client/src/profile/index.ts @@ -70,9 +70,9 @@ export class Profile { } public async create(handle: string): Promise { - const proposolResponse = await this.graphQlClient.get(getProtocolById(1)); + const proposalResponse = await this.graphQlClient.get(getProtocolById(1)); - const protocol = proposolResponse?.data?.protocol; + const protocol = proposalResponse?.data?.protocol; console.log('SDK: protocol', protocol); From eda0a005d03a7d52b92a2888702f600283048c84 Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Wed, 29 Nov 2023 17:02:09 +0000 Subject: [PATCH 22/40] Removed rateToken from Service Metadata type --- packages/client/src/services/types/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/client/src/services/types/index.ts b/packages/client/src/services/types/index.ts index cd0bbe6..b70fa1f 100644 --- a/packages/client/src/services/types/index.ts +++ b/packages/client/src/services/types/index.ts @@ -25,7 +25,6 @@ export type ServiceDetails = { title: string; about: string; keywords: string; - rateToken: string; rateAmount: string; [key: string]: any; }; From 8f399f511b329972a01e5aa88bf3a38610e9847b Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Wed, 29 Nov 2023 20:22:13 +0000 Subject: [PATCH 23/40] Modified queries --- packages/client/src/__mocks__/fixtures.ts | 16 ++++++++-------- packages/client/src/graphql/queries.ts | 12 +++++++++--- packages/client/src/profile/graphql/index.ts | 6 +++--- packages/client/src/proposals/graphql/index.ts | 4 ++-- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/packages/client/src/__mocks__/fixtures.ts b/packages/client/src/__mocks__/fixtures.ts index db0a6c0..559f275 100644 --- a/packages/client/src/__mocks__/fixtures.ts +++ b/packages/client/src/__mocks__/fixtures.ts @@ -13,7 +13,7 @@ export const testUserResponse = { handle: 'talentlayer', rating: '0', delegates: [], - userStats: { numReceivedReviews: '0' }, + userStat: { numReceivedReviews: '0' }, updatedAt: '1680621215', createdAt: '1680608213', description: { @@ -65,7 +65,7 @@ export const mockGraphQlProtocolByIdResponse = { export const testIpfsHash = 'abcd'; export const testCid = testIpfsHash; export const testProfileData = { name: testName, about: testAbout }; -export const testGetProfilesResponse = { "data": { "users": [{ "id": "11962", "address": "0x02289d0ebf8836e6f98af170b88b9f8eb889e2c6", "handle": "racoon", "userStats": { "numReceivedReviews": "0" }, "rating": "0" }] } } +export const testGetProfilesResponse = { "data": { "users": [{ "id": "11962", "address": "0x02289d0ebf8836e6f98af170b88b9f8eb889e2c6", "handle": "racoon", "userStat": { "numReceivedReviews": "0" }, "rating": "0" }] } } export const testUserTotalGainsResponse = { data: { user: { totalGains: [{ "id": "2371-0x2791bca1f2de4661ed88a30c99a7a9449aa84174", "totalGain": "850000000", "token": { "id": "0xracoon", "name": "USD Coin (PoS)", "symbol": "USDC", "decimals": "6" } }] } } } export const testUserPaymentsResponse = { data: { payments: [{ "id": "0x3eb5973863d712ce78dc757af04ca24a81d0376dbce604d002779475428e4a85-975", "rateToken": { "address": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174", "decimals": "6", "name": "USD Coin (PoS)", "symbol": "USDC" }, "amount": "850000000", "transactionHash": "0x3eb5973863d712ce78dc757af04ca24a81d0376dbce604d002779475428e4a85", "paymentType": "Release", "createdAt": "1699361940", "service": { "id": "75", "cid": "abcd" } }] } } @@ -74,13 +74,13 @@ export const testPlatformResponse = { "data": { "platform": { "id": "1", "addres export const testPlatformResponseWithArbitrator = { "data": { "platform": { "id": "1", "address": "0xracoon", "name": "abcd", "createdAt": "1681454011", "updatedAt": "1681454011", "originServiceFeeRate": 0, "originValidatedProposalFeeRate": 0, "servicePostingFee": "0", "proposalPostingFee": "0", "arbitrator": "0xracoon", "arbitratorExtraData": "0x00000000", "arbitrationFeeTimeout": "864000", "cid": null, "signer": "0xraqcoon", "description": null } } } export const testProposalId = '12-83'; export const testProposalIdWithDifferentRateToken = '12-84'; -export const testProposalResponse = { "data": { "proposal": { "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" } } }; -export const testProposalResponseWithDifferentRateToken = { "data": { "proposal": { "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": testAddress }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" } } } +export const testProposalResponse = { "data": { "proposal": { "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStat": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" } } }; +export const testProposalResponseWithDifferentRateToken = { "data": { "proposal": { "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStat": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": testAddress }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" } } } export const testProtocolAndPlatformResponse = { "data": { "protocols": [{ "protocolEscrowFeeRate": 100 }], "servicePlatform": { "originServiceFeeRate": 0 }, "proposalPlatform": { "originValidatedProposalFeeRate": 0 } } } export const testServiceId = '12'; // rest to 12 before comitting export const testAmount = BigInt('1000'); -export const testServiceResponse = { "data": { "service": { "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ", "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } } } }; -export const testSearchServicesResponse = { data: { "services": [{ "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ", "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } }] } } +export const testServiceResponse = { "data": { "service": { "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ", "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStat": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } } } }; +export const testSearchServicesResponse = { data: { "services": [{ "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ", "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStat": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } }] } } export const testServiceDetails = { title: 'test title', about: 'test about', @@ -98,8 +98,8 @@ export const testPlatformDetails = { export const testOwnerAddress = '0xOwnerAddress'; export const testPlatformsByOwnerResponse = { "data": { "platforms": [{ "id": "1", "address": "0x4444444e2f8ccd0e323c959b02a93561b911f9b6", "name": "workx", "createdAt": "1681454011", "updatedAt": "1681454011", "originServiceFeeRate": 0, "originValidatedProposalFeeRate": 0, "servicePostingFee": "0", "proposalPostingFee": "0", "arbitrator": "0x0000000000000000000000000000000000000000", "arbitratorExtraData": "0x00000000", "arbitrationFeeTimeout": "864000", "cid": null, "signer": "0x4444444e2f8ccd0e323c959b02a93561b911f9b6", "description": null }] } } -export const testProposalsByServiceId = { "data": { "proposals": [{ "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" }] } } -export const testProposalsByUser = { "data": { "proposals": [{ "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" }] } } +export const testProposalsByServiceId = { "data": { "proposals": [{ "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStat": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" }] } } +export const testProposalsByUser = { "data": { "proposals": [{ "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStat": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" }] } } export const testProposalDetails = { about: 'test about', video_url: 'hello world' } export const testExpirationDate = '123456'; export const testSignature = ''; diff --git a/packages/client/src/graphql/queries.ts b/packages/client/src/graphql/queries.ts index 7044acf..8f32b45 100644 --- a/packages/client/src/graphql/queries.ts +++ b/packages/client/src/graphql/queries.ts @@ -3,6 +3,13 @@ export const serviceQueryFields = ` status createdAt cid + referralAmount + rateToken { + address + decimals + name + symbol + } transaction { id } @@ -11,7 +18,7 @@ export const serviceQueryFields = ` handle address rating - userStats { + userStat { numReceivedReviews } } @@ -42,7 +49,6 @@ export const serviceDescriptionQueryFields = ` startDate expectedEndDate rateAmount - rateToken keywords_raw keywords { id @@ -59,7 +65,7 @@ export const getProposalsByService = (serviceId: string) => ` address cid rating - userStats { + userStat { numReceivedReviews } } diff --git a/packages/client/src/profile/graphql/index.ts b/packages/client/src/profile/graphql/index.ts index e7b1b79..e88ba51 100644 --- a/packages/client/src/profile/graphql/index.ts +++ b/packages/client/src/profile/graphql/index.ts @@ -9,7 +9,7 @@ export const getProfileByAddress = (address: Hash) => handle rating delegates - userStats { + userStat { numReceivedReviews } updatedAt @@ -43,7 +43,7 @@ export const getProfiles = (numberPerPage?: number, offset?: number, searchQuery id address handle - userStats { + userStat { numReceivedReviews } rating @@ -60,7 +60,7 @@ export const getProfileById = (id: string) => ` handle rating delegates - userStats { + userStat { numReceivedReviews } updatedAt diff --git a/packages/client/src/proposals/graphql/index.ts b/packages/client/src/proposals/graphql/index.ts index 0ad8e24..a7db950 100644 --- a/packages/client/src/proposals/graphql/index.ts +++ b/packages/client/src/proposals/graphql/index.ts @@ -8,7 +8,7 @@ export const getProposalById = (id: string) => ` address cid rating - userStats { + userStat { numReceivedReviews } } @@ -67,7 +67,7 @@ export const getAllProposalsByServiceId = (id: string) => ` address cid rating - userStats { + userStat { numReceivedReviews } } From 0d5f65cc0959895b256f7c323a0326032d441fab Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Wed, 29 Nov 2023 20:22:22 +0000 Subject: [PATCH 24/40] Updated ABIs --- .../src/contracts/ABI/TalentLayerEscrow.json | 155 +++++++++- .../src/contracts/ABI/TalentLayerService.json | 278 ++++++++++++++++-- 2 files changed, 405 insertions(+), 28 deletions(-) diff --git a/packages/client/src/contracts/ABI/TalentLayerEscrow.json b/packages/client/src/contracts/ABI/TalentLayerEscrow.json index 1e48db0..5bb842b 100644 --- a/packages/client/src/contracts/ABI/TalentLayerEscrow.json +++ b/packages/client/src/contracts/ABI/TalentLayerEscrow.json @@ -355,6 +355,49 @@ "name": "_amount", "type": "uint256" }, + { + "indexed": false, + "internalType": "uint256", + "name": "_serviceId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_proposalId", + "type": "uint256" + } + ], + "name": "Payment", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_transactionId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "enum TalentLayerEscrowV1.PaymentType", + "name": "_paymentType", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, { "indexed": false, "internalType": "uint256", @@ -391,6 +434,62 @@ "name": "ProtocolEscrowFeeRateUpdated", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_referrerId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "ReferralAmountClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_referrerId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_serviceId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "ReferralAmountReleased", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -629,6 +728,24 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_referrerId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_tokenAddress", + "type": "address" + } + ], + "name": "claimReferralBalance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -701,6 +818,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "getClaimableReferralBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -807,6 +943,21 @@ "internalType": "uint256", "name": "arbitrationFeeTimeout", "type": "uint256" + }, + { + "internalType": "uint256", + "name": "referrerId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "referralAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalAmount", + "type": "uint256" } ], "internalType": "struct TalentLayerEscrow.Transaction", @@ -1147,8 +1298,8 @@ "type": "function" } ], - "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b60805161501262000120600039600081816114df0152818161151f015281816118e80152818161192801526119b701526150126000f3fe6080604052600436106101cd5760003560e01c80635a34257a116100f75780638b69fa0a11610095578063e308a09911610064578063e308a09914610523578063eb63612d14610543578063f2fde38b14610563578063f8c8765e1461058357600080fd5b80638b69fa0a146104a55780638da5cb5b146104c55780639dcc5daf146104e3578063ddd5e1b21461050357600080fd5b8063715018a6116100d1578063715018a6146104555780637b44cdb51461046a5780637e69b7b01461047d5780638456cb591461049057600080fd5b80635a34257a146103f45780635c975abb1461042a5780636e72b4521461044257600080fd5b80633659cfe61161016f5780633f4ba83a1161013e5780633f4ba83a1461036e5780634f1ef2861461038357806352d1902d14610396578063572b6c05146103ab57600080fd5b80633659cfe6146102ee5780633751d89c1461030e5780633a1121cd1461032e5780633ab4a6a41461034e57600080fd5b806315734fe7116101ab57806315734fe71461026b57806326d006681461027e5780632fbe3b03146102a0578063311a6c56146102ce57600080fd5b806306d6e63f146101d25780630a1a47d6146102105780630fa683d31461023e575b600080fd5b3480156101de57600080fd5b50610101546101f3906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021c57600080fd5b5061023061022b3660046140e6565b6105a3565b604051908152602001610207565b34801561024a57600080fd5b5061025e610259366004614103565b61070f565b6040516102079190614196565b61023061027936600461442c565b610a5d565b34801561028a57600080fd5b5061029e6102993660046140e6565b611303565b005b3480156102ac57600080fd5b506102306102bb366004614103565b6101026020526000908152604090205481565b3480156102da57600080fd5b5061029e6102e93660046144a3565b611366565b3480156102fa57600080fd5b5061029e6103093660046140e6565b6114d5565b34801561031a57600080fd5b5061029e6103293660046140e6565b6115b4565b34801561033a57600080fd5b5061029e6103493660046144c5565b61160d565b34801561035a57600080fd5b5061029e610369366004614103565b611716565b34801561037a57600080fd5b5061029e6118cc565b61029e6103913660046144f1565b6118de565b3480156103a257600080fd5b506102306119aa565b3480156103b757600080fd5b506103e46103c63660046140e6565b6001600160a01b031660009081526065602052604090205460ff1690565b6040519015158152602001610207565b34801561040057600080fd5b506101015461041790600160a01b900461ffff1681565b60405161ffff9091168152602001610207565b34801561043657600080fd5b5060665460ff166103e4565b61029e610450366004614103565b611a5d565b34801561046157600080fd5b5061029e611cf6565b61029e610478366004614103565b611d08565b61029e61048b366004614103565b611f82565b34801561049c57600080fd5b5061029e61203a565b3480156104b157600080fd5b5061029e6104c0366004614555565b61204a565b3480156104d157600080fd5b506033546001600160a01b03166101f3565b3480156104ef57600080fd5b5061029e6104fe3660046144c5565b6123ad565b34801561050f57600080fd5b5061029e61051e3660046145a5565b61249b565b34801561052f57600080fd5b5061029e61053e3660046140e6565b6126af565b34801561054f57600080fd5b5061029e61055e3660046145e5565b6126da565b34801561056f57600080fd5b5061029e61057e3660046140e6565b612733565b34801561058f57600080fd5b5061029e61059e366004614602565b6127a9565b6000806105ae61292a565b9050806001600160a01b03166105cc6033546001600160a01b031690565b6001600160a01b0316036106165750506001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc602052604090205490565b61010054604051631847c06b60e01b81526001600160a01b0383811660048301526000921690631847c06b90602401602060405180830381865afa158015610662573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610686919061465e565b6101005460405162f577a560e81b8152600481018390529192506001600160a01b03169063f577a5009060240160006040518083038186803b1580156106cb57600080fd5b505afa1580156106df573d6000803e3d6000fd5b50505060009182525060fd602090815260408083206001600160a01b039096168352949052929092205492915050565b6107a96040805161026081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290529061018082019081526020016000815260200160008152602001600081526020016000815260200160608152602001600081525090565b600082815260fc602090815260408083208151610260810183528154815260018201546001600160a01b039081169482019490945260028201548416928101929092526003810154831660608301526004808201546080840152600582015460a0840152600682015460c0840152600782015460e0840152600882015461ffff8082166101008601526201000082048116610120860152640100000000820416610140850152600160301b810490941661016084015291929091610180840191600160d01b900460ff16908111156108835761088361411c565b60048111156108945761089461411c565b815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d820180546108d090614677565b80601f01602080910402602001604051908101604052809291908181526020018280546108fc90614677565b80156109495780601f1061091e57610100808354040283529160200191610949565b820191906000526020600020905b81548152906001019060200180831161092c57829003601f168201915b50505050508152602001600e8201548152505090506109686101035490565b8151106109b55760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064015b60405180910390fd5b60006109bf61292a565b905081602001516001600160a01b0316816001600160a01b031614806109fa575081604001516001600160a01b0316816001600160a01b0316145b610a565760405162461bcd60e51b815260206004820152602760248201527f596f7520617265206e6f742072656c6174656420746f2074686973207472616e60448201526639b0b1ba34b7b760c91b60648201526084016109ac565b5092915050565b6000610a67612939565b60fe5460405163353bb87f60e21b8152600481018790526024810186905260009182916001600160a01b039091169063d4eee1fc90604401600060405180830381865afa158015610abc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ae491908101906147a7565b60ff54602083810151908301516040516303ef723760e61b81526004810192909252602482015292945090925060009182916001600160a01b03169063fbdc8dc0906044016040805180830381865afa158015610b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b699190614872565b6101005460a0870151604051630b7a459360e31b815260048101919091529294509092506000916001600160a01b0390911690635bd22c9890602401600060405180830381865afa158015610bc2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610bea91908101906148ac565b9050600084608001518660a0015103610c035781610c80565b610100546080860151604051630b7a459360e31b81526001600160a01b0390921691635bd22c9891610c3b9160040190815260200190565b600060405180830381865afa158015610c58573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c8091908101906148ac565b90506000610c9b86606001518460600151846080015161297f565b60408701519091506001600160a01b0316610cf957803414610cf45760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016109ac565b610d3c565b3415610d3c5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016109ac565b846001600160a01b0316610d4e61292a565b6001600160a01b031614610d745760405162461bcd60e51b81526004016109ac906149d8565b8a866020015114610dbf5760405162461bcd60e51b8152602060048201526015602482015274125b98dbdc9c9958dd081c1c9bdc1bdcd85b081251605a1b60448201526064016109ac565b428660c001511015610e065760405162461bcd60e51b815260206004820152601060248201526f141c9bdc1bdcd85b08195e1c1a5c995960821b60448201526064016109ac565b600087516004811115610e1b57610e1b61411c565b14610e685760405162461bcd60e51b815260206004820152601760248201527f5365727669636520737461747573206e6f74206f70656e00000000000000000060448201526064016109ac565b600086516001811115610e7d57610e7d61411c565b14610eca5760405162461bcd60e51b815260206004820152601b60248201527f50726f706f73616c20737461747573206e6f742070656e64696e67000000000060448201526064016109ac565b8951602e14610f095760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b60448201526064016109ac565b88604051602001610f1a91906149ff565b604051602081830303815290604052805190602001208660a00151604051602001610f4591906149ff565b6040516020818303038152906040528051906020012014610fa85760405162461bcd60e51b815260206004820152601c60248201527f50726f706f73616c206461746155726920686173206368616e6765640000000060448201526064016109ac565b6000610fb46101035490565b9050604051806102600160405280828152602001876001600160a01b03168152602001866001600160a01b0316815260200188604001516001600160a01b0316815260200188606001518152602001600081526020018e81526020018d815260200161010160149054906101000a900461ffff1661ffff168152602001856060015161ffff168152602001846080015161ffff1681526020018560e001516001600160a01b03168152602001600060048111156110735761107361411c565b8152600060208083018290526040808401839052606080850184905242608080870191909152610100808c015160a080890191909152610120808e015160c0998a01528a885260fc87529685902089518155958901516001870180546001600160a01b039283166001600160a01b031991821617909155958a01516002880180549183169188169190911790559389015160038701805491861691909616179094559087015160048086019190915592870151600585015594860151600684015560e086015160078401559385015160088301805494870151610140880151610160890151909716600160301b026601000000000000600160d01b031961ffff9889166401000000000216640100000000600160d01b0319928916620100000263ffffffff19909816989094169790971795909517949094161793909317808355610180850151919391929160ff60d01b1990911690600160d01b9084908111156111e0576111e061411c565b02179055506101a082015160098201556101c0820151600a8201556101e0820151600b820155610200820151600c820155610220820151600d8201906112269082614a61565b5061024082015181600e015590505061124461010380546001019055565b60fe546040516353eaf57560e11b8152600481018f9052602481018e9052604481018390526001600160a01b039091169063a7d5eaea90606401600060405180830381600087803b15801561129857600080fd5b505af11580156112ac573d6000803e3d6000fd5b5050505060408701516001600160a01b0316156112dd5760408701516112dd906001600160a01b03168730856129eb565b6112f188602001518860200151838e612a4b565b9750505050505050505b949350505050565b61130b612b66565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b600061137061292a565b6000848152610102602090815260408083205480845260fc909252909120600881015492935090916001600160a01b03808516600160301b90920416146114035760405162461bcd60e51b815260206004820152602160248201527f5468652063616c6c6572206d757374206265207468652061726269747261746f6044820152603960f91b60648201526084016109ac565b60036008820154600160d01b900460ff1660048111156114255761142561411c565b146114805760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652068617320616c7265616479206265656e207265736044820152641bdb1d995960da1b60648201526084016109ac565b84836001600160a01b03167f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e75622276866040516114bc91815260200190565b60405180910390a36114ce8285612bdf565b5050505050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361151d5760405162461bcd60e51b81526004016109ac90614b21565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611566600080516020614f76833981519152546001600160a01b031690565b6001600160a01b03161461158c5760405162461bcd60e51b81526004016109ac90614b6d565b61159581612e69565b604080516000808252602082019092526115b191839190612e71565b50565b6115bc612b66565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee6910161135b565b611615612939565b60ff5483906001600160a01b0316632fa117e58261163161292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561167b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169f9190614bb9565b6116bb5760405162461bcd60e51b81526004016109ac90614bdb565b6116c88360008685612fdc565b600083815260fc60205260408120600481018054919285926116eb908490614c20565b92505081905550828160050160008282546117069190614c33565b909155506114ce905084846132c7565b600081815260fc60205260409020600e810154600c8201546117389042614c20565b10156117865760405162461bcd60e51b815260206004820152601f60248201527f54696d656f75742074696d6520686173206e6f7420706173736564207965740060448201526064016109ac565b60016008820154600160d01b900460ff1660048111156117a8576117a861411c565b0361182b57600a8101541561181c57600a81018054600091829055600183015460405191926001600160a01b0390911691839181818185875af1925050503d8060008114611812576040519150601f19603f3d011682016040523d82523d6000602084013e611817565b606091505b505050505b611827826002612bdf565b5050565b60026008820154600160d01b900460ff16600481111561184d5761184d61411c565b0361182757600b810154156118c157600b81018054600091829055600283015460405191926001600160a01b0390911691839181818185875af1925050503d80600081146118b7576040519150601f19603f3d011682016040523d82523d6000602084013e6118bc565b606091505b505050505b611827826001612bdf565b6118d4612b66565b6118dc61330c565b565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036119265760405162461bcd60e51b81526004016109ac90614b21565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661196f600080516020614f76833981519152546001600160a01b031690565b6001600160a01b0316146119955760405162461bcd60e51b81526004016109ac90614b6d565b61199e82612e69565b61182782826001612e71565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a4a5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016109ac565b50600080516020614f7683398151915290565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611a9c5760405162461bcd60e51b81526004016109ac90614c46565b60036008820154600160d01b900460ff166004811115611abe57611abe61411c565b10611adb5760405162461bcd60e51b81526004016109ac90614c72565b60028101546001600160a01b0316611af161292a565b6001600160a01b031614611b475760405162461bcd60e51b815260206004820152601f60248201527f5468652063616c6c6572206d757374206265207468652072656365697665720060448201526064016109ac565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611b8490600d860190600401614d62565b602060405180830381865afa158015611ba1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc5919061465e565b90503482600b016000828254611bdb9190614c33565b9091555050600b8201548114611c525760405162461bcd60e51b815260206004820152603660248201527f54686520726563656976657220666565206d75737420626520657175616c20746044820152751bc81d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60521b60648201526084016109ac565b42600c8301556040518390600080516020614f9683398151915290611c7e906000906001903490614d85565b60405180910390a28082600a01541015611ce75760088201805460ff60d01b1916600160d01b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611cda90600090614daf565b60405180910390a2505050565b611cf18382613364565b505050565b611cfe612b66565b6118dc60006135b7565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611d475760405162461bcd60e51b81526004016109ac90614c46565b60036008820154600160d01b900460ff166004811115611d6957611d6961411c565b10611d865760405162461bcd60e51b81526004016109ac90614c72565b60018101546001600160a01b0316611d9c61292a565b6001600160a01b031614611df25760405162461bcd60e51b815260206004820152601d60248201527f5468652063616c6c6572206d757374206265207468652073656e64657200000060448201526064016109ac565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611e2f90600d860190600401614d62565b602060405180830381865afa158015611e4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e70919061465e565b90503482600a016000828254611e869190614c33565b9091555050600a8201548114611efb5760405162461bcd60e51b815260206004820152603460248201527f5468652073656e64657220666565206d75737420626520657175616c20746f206044820152731d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60621b60648201526084016109ac565b42600c8301556040518390600080516020614f9683398151915290611f269060009081903490614d85565b60405180910390a28082600b01541015611ce75760088201805460ff60d01b1916600160d11b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611cda90600190614daf565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611fc15760405162461bcd60e51b81526004016109ac90614c46565b6008810154600982015460405163093225f160e31b8152600160301b9092046001600160a01b0316916349912f889134916120049190600d870190600401614dc2565b6000604051808303818588803b15801561201d57600080fd5b505af1158015612031573d6000803e3d6000fd5b50505050505050565b612042612b66565b6118dc613609565b60ff5483906001600160a01b0316632fa117e58261206661292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156120b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d49190614bb9565b6120f05760405162461bcd60e51b81526004016109ac90614bdb565b8151602e1461212f5760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b60448201526064016109ac565b600083815260fc602052604090206008810154600160301b90046001600160a01b031661216e5760405162461bcd60e51b81526004016109ac90614c46565b60ff546040516331a9108f60e11b8152600481018790526000916001600160a01b031690636352211e90602401602060405180830381865afa1580156121b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121dc9190614ddb565b60018301549091506001600160a01b038083169116148061220c575060028201546001600160a01b038281169116145b612280576040805162461bcd60e51b81526020600482015260248101919091527f5468652063616c6c6572206d757374206265207468652073656e646572206f7260448201527f20746865207265636569766572206f722074686569722064656c65676174657360648201526084016109ac565b60046008830154600160d01b900460ff1660048111156122a2576122a261411c565b106123095760405162461bcd60e51b815260206004820152603160248201527f4d757374206e6f742073656e642065766964656e6365206966207468652064696044820152701cdc1d5d19481a5cc81c995cdbdb1d9959607a1b60648201526084016109ac565b806001600160a01b0316858360080160069054906101000a90046001600160a01b03166001600160a01b03167fdccf2f8b2cc26eafcd61905cba744cff4b81d14740725f6376390dc6298a6a3c876040516123649190614df8565b60405180910390a485857fd998ce0f89c38b0f93256f0b843a404a3a3c5055b75265623f7cb9c369a1dd628660405161239d9190614df8565b60405180910390a3505050505050565b6123b5612939565b60ff5483906001600160a01b0316632fa117e5826123d161292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561241b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243f9190614bb9565b61245b5760405162461bcd60e51b81526004016109ac90614bdb565b6124688360018685612fdc565b600083815260fc602052604081206004810180549192859261248b908490614c20565b909155506114ce90508484613647565b6124a3612939565b60006124ad61292a565b6001600160a01b03166124c86033546001600160a01b031690565b6001600160a01b0316036125075782156124f45760405162461bcd60e51b81526004016109ac906149d8565b50610101546001600160a01b03166125d4565b6101005460405162f577a560e81b8152600481018590526001600160a01b039091169063f577a5009060240160006040518083038186803b15801561254b57600080fd5b505afa15801561255f573d6000803e3d6000fd5b5050610100546040516331a9108f60e11b8152600481018790526001600160a01b039091169250636352211e9150602401602060405180830381865afa1580156125ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d19190614ddb565b90505b600083815260fd602090815260408083206001600160a01b0386168452909152902054806126375760405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b60448201526064016109ac565b600084815260fd602090815260408083206001600160a01b03871684529091528120556126658284836136ad565b60408051858152602081018390526001600160a01b038516917f2227733fc4c8a9034cb58087dcf6995128b9c0233b038b03366aaf30c92b92d6910160405180910390a250505050565b6126b7612b66565b61010180546001600160a01b0319166001600160a01b0392909216919091179055565b6126e2612b66565b610101805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f8339189e972f7fba792126e752aa8485af08710bce4a041c5bc3f9858acd71309060200161135b565b61273b612b66565b6001600160a01b0381166127a05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109ac565b6115b1816135b7565b600054610100900460ff16158080156127c95750600054600160ff909116105b806127e35750303b1580156127e3575060005460ff166001145b6128465760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016109ac565b6000805460ff191660011790558015612869576000805461ff0019166101001790555b612871613787565b6128796137b6565b60fe80546001600160a01b038088166001600160a01b03199283161790925560ff805487841690831617905561010080548684169083161790556101018054928516929091169190911790556128d461010380546001019055565b6128de60646126da565b80156114ce576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b60006129346137dd565b905090565b60665460ff16156118dc5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016109ac565b600061271061299261ffff841686614e0b565b6129a061ffff861687614e0b565b610101546129b990600160a01b900461ffff1688614e0b565b6129c39190614c33565b6129cd9190614c33565b6129d79190614e22565b6129e19085614c33565b90505b9392505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612a45908590613816565b50505050565b600060fc600084815260200190815260200160002090507f8b4f0e94aa0aee74c276abd2d92a5e2737a493b055e19d5b2d4c0ac573242a158386868460030160009054906101000a90046001600160a01b031685600401548660060154876007015461010160149054906101000a900461ffff168960080160029054906101000a900461ffff168a60080160049054906101000a900461ffff168b60080160069054906101000a90046001600160a01b03168c600d018d600e0154604051612b1f9d9c9b9a99989796959493929190614e44565b60405180910390a1827f61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d83604051612b579190614df8565b60405180910390a25050505050565b612b6e61292a565b6001600160a01b0316612b896033546001600160a01b031690565b6001600160a01b0316146118dc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ac565b600082815260fc602052604090206002821115612c2f5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c69642072756c696e6760901b60448201526064016109ac565b60018101546002820154600483018054600a85018054600b87018054600095869055928590559390935560088601805460ff60d01b1916600160d21b1790556001600160a01b0394851694909316929091906000198701612cea576040516001600160a01b038616908390600081818185875af1925050503d8060008114612cd3576040519150601f19603f3d011682016040523d82523d6000602084013e612cd8565b606091505b505050612ce58884613647565b612e25565b6001198701612d4e576040516001600160a01b038516908290600081818185875af1925050503d8060008114612d3c576040519150601f19603f3d011682016040523d82523d6000602084013e612d41565b606091505b505050612ce588846132c7565b6000612d5b600284614e22565b90506000612d6a600286614e22565b9050612d768a82613647565b612d808a826132c7565b6040516001600160a01b038816908390600081818185875af1925050503d8060008114612dc9576040519150601f19603f3d011682016040523d82523d6000602084013e612dce565b606091505b50506040516001600160a01b03881691508390600081818185875af1925050503d8060008114612e1a576040519150601f19603f3d011682016040523d82523d6000602084013e612e1f565b606091505b50505050505b877f76b363d70472d47d20e4119f3625c05ed37ca51b1d9e1cd8b87d8c20530640f388604051612e5791815260200190565b60405180910390a25050505050505050565b6115b1612b66565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612ea457611cf1836138e8565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612efe575060408051601f3d908101601f19168201909252612efb9181019061465e565b60015b612f615760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016109ac565b600080516020614f768339815191528114612fd05760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016109ac565b50611cf1838383613984565b600084815260fc6020526040812090846001811115612ffd57612ffd61411c565b036130a35760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa15801561304b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306f9190614ddb565b60018201546001600160a01b0390811691161461309e5760405162461bcd60e51b81526004016109ac906149d8565b613158565b60018460018111156130b7576130b761411c565b036131585760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa158015613105573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131299190614ddb565b60028201546001600160a01b039081169116146131585760405162461bcd60e51b81526004016109ac906149d8565b610103548154106131a45760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064016109ac565b60006008820154600160d01b900460ff1660048111156131c6576131c661411c565b146132215760405162461bcd60e51b815260206004820152602560248201527f546865207472616e73616374696f6e2073686f756c646e2774206265206469736044820152641c1d5d195960da1b60648201526084016109ac565b818160040154101561326a5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b60448201526064016109ac565b6127108210158061328a57506127108210801561328a5750806004015482145b6114ce5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016109ac565b6132d182826139a9565b600082815260fc6020526040902060028101546003820154613300916001600160a01b039081169116846136ad565b611cf183600084613c57565b613314613d79565b6066805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61334761292a565b6040516001600160a01b03909116815260200160405180910390a1565b600082815260fc60205260409081902060088101805460ff60d01b1916600360d01b1790819055915163c13517e160e01b81529091600160301b90046001600160a01b031690819063c13517e19085906133c890600290600d880190600401614ed2565b60206040518083038185885af11580156133e6573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061340b919061465e565b600983018181556000918252610102602090815260409283902087905590548251878152918201879052916001600160a01b038416917f74baab670a4015ab2f1b467c5252a96141a2573f2908e58a92081e80d3cfde3d910160405180910390a38282600a015411156135175760008383600a015461348a9190614c20565b600a840185905560018401546040519192506001600160a01b0316908290600081818185875af1925050503d80600081146134e1576040519150601f19603f3d011682016040523d82523d6000602084013e6134e6565b606091505b50505084600080516020614f96833981519152600160003460405161350d93929190614d85565b60405180910390a2505b8282600b01541115612a455760008383600b01546135359190614c20565b600b840185905560028401546040519192506001600160a01b0316908290600081818185875af1925050503d806000811461358c576040519150601f19603f3d011682016040523d82523d6000602084013e613591565b606091505b50505084600080516020614f9683398151915260018034604051612b5793929190614d85565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b613611612939565b6066805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861334761292a565b600082815260fc60205260408120600881015490919061367d90849061ffff62010000820481169164010000000090041661297f565b600183015460038401549192506136a1916001600160a01b039182169116836136ad565b612a4584600185613c57565b6001600160a01b038216600003613714576040516001600160a01b038416908290600081818185875af1925050503d8060008114613707576040519150601f19603f3d011682016040523d82523d6000602084013e61370c565b606091505b505050505050565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb906044016020604051808303816000875af1158015613763573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a459190614bb9565b600054610100900460ff166137ae5760405162461bcd60e51b81526004016109ac90614eee565b6118dc613dc2565b600054610100900460ff166118dc5760405162461bcd60e51b81526004016109ac90614eee565b6000601436108015906137ff57503360009081526065602052604090205460ff165b15613811575060131936013560601c90565b503390565b600061386b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613df99092919063ffffffff16565b805190915015611cf157808060200190518101906138899190614bb9565b611cf15760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109ac565b6001600160a01b0381163b6139555760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016109ac565b600080516020614f7683398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61398d83613e08565b60008251118061399a5750805b15611cf157612a458383613e48565b600082815260fc602052604080822060fe5460068201546007830154935163353bb87f60e21b81526004810191909152602481019390935290929182916001600160a01b03169063d4eee1fc90604401600060405180830381865afa158015613a16573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613a3e91908101906147a7565b60a0820151608082015160088701549395509193509160009061271090613a6a90899061ffff16614e0b565b613a749190614e22565b600887015490915060009061271090613a98908a9062010000900461ffff16614e0b565b613aa29190614e22565b600888015490915060009061271090613ac8908b90640100000000900461ffff16614e0b565b613ad29190614e22565b60038901546001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc6020526040812080549293508592909190613b22908490614c33565b9091555050600085815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054849290613b5d908490614c33565b9091555050600084815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054839290613b98908490614c33565b90915550506003880154600689015460408051888152602081019290925281018490526001600160a01b03909116907f17c48ab8e1617182f35ae77fd7da7f4e15dedf7018aa371a4481c20c790b65469060600160405180910390a26003880154600689015460408051878152602081019290925281018490526001600160a01b03909116907f3476ed3eea2cdac584273bc8830824c8ca42ca2a99e9f144a87a1cdbbf9dd15a9060600160405180910390a250505050505050505050565b600083815260fc602052604090819020805460038201546006830154935192937f2ab2a30b19f7bc6e386d4ee60aa21ed23c127ce9fe26903da97edd54bad0375a93613cb4939288926001600160a01b0390911691889190614f39565b60405180910390a18060040154600003612a455760fe5460068201546005830154604051635ab9ae0f60e11b8152600481019290925260248201526001600160a01b039091169063b5735c1e90604401600060405180830381600087803b158015613d1e57600080fd5b505af1158015613d32573d6000803e3d6000fd5b505050507f6bef1b5e95b741d6e665eb9b5c2d3e1203c46a771451055a9d41e0b8ff4510b78160060154604051613d6b91815260200190565b60405180910390a150505050565b60665460ff166118dc5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016109ac565b600054610100900460ff16613de95760405162461bcd60e51b81526004016109ac90614eee565b6118dc613df461292a565b6135b7565b60606129e18484600085613f3e565b613e11816138e8565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b613eb05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016109ac565b600080846001600160a01b031684604051613ecb91906149ff565b600060405180830381855af49150503d8060008114613f06576040519150601f19603f3d011682016040523d82523d6000602084013e613f0b565b606091505b5091509150613f338282604051806060016040528060278152602001614fb660279139614019565b925050505b92915050565b606082471015613f9f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016109ac565b600080866001600160a01b03168587604051613fbb91906149ff565b60006040518083038185875af1925050503d8060008114613ff8576040519150601f19603f3d011682016040523d82523d6000602084013e613ffd565b606091505b509150915061400e87838387614032565b979650505050505050565b606083156140285750816129e4565b6129e483836140a7565b606083156140a157825160000361409a576001600160a01b0385163b61409a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109ac565b50816112fb565b6112fb83835b8151156140b75781518083602001fd5b8060405162461bcd60e51b81526004016109ac9190614df8565b6001600160a01b03811681146115b157600080fd5b6000602082840312156140f857600080fd5b81356129e4816140d1565b60006020828403121561411557600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b600581106141425761414261411c565b9052565b60005b83811015614161578181015183820152602001614149565b50506000910152565b60008151808452614182816020860160208601614146565b601f01601f19169290920160200192915050565b6020815281516020820152600060208301516141bd60408401826001600160a01b03169052565b5060408301516001600160a01b03811660608401525060608301516001600160a01b038116608084015250608083015160a083015260a083015160c083015260c083015160e083015260e083015161010081818501528085015191505061012061422c8185018361ffff169052565b84015190506101406142438482018361ffff169052565b840151905061016061425a8482018361ffff169052565b8401519050610180614276848201836001600160a01b03169052565b84015190506101a061428a84820183614132565b8401516101c0848101919091528401516101e0808501919091528401516102008085019190915284015161022080850191909152840151610260610240808601829052919250906142df61028086018461416a565b9501519301929092525090919050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff81118282101715614328576143286142ef565b60405290565b60405160c0810167ffffffffffffffff81118282101715614328576143286142ef565b604051610160810167ffffffffffffffff81118282101715614328576143286142ef565b604051601f8201601f1916810167ffffffffffffffff8111828210171561439e5761439e6142ef565b604052919050565b600067ffffffffffffffff8211156143c0576143c06142ef565b50601f01601f191660200190565b60006143e16143dc846143a6565b614375565b90508281528383830111156143f557600080fd5b828260208301376000602084830101529392505050565b600082601f83011261441d57600080fd5b6129e4838335602085016143ce565b6000806000806080858703121561444257600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561446857600080fd5b6144748883890161440c565b9350606087013591508082111561448a57600080fd5b506144978782880161440c565b91505092959194509250565b600080604083850312156144b657600080fd5b50508035926020909101359150565b6000806000606084860312156144da57600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561450457600080fd5b823561450f816140d1565b9150602083013567ffffffffffffffff81111561452b57600080fd5b8301601f8101851361453c57600080fd5b61454b858235602084016143ce565b9150509250929050565b60008060006060848603121561456a57600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561458f57600080fd5b61459b8682870161440c565b9150509250925092565b600080604083850312156145b857600080fd5b8235915060208301356145ca816140d1565b809150509250929050565b61ffff811681146115b157600080fd5b6000602082840312156145f757600080fd5b81356129e4816145d5565b6000806000806080858703121561461857600080fd5b8435614623816140d1565b93506020850135614633816140d1565b92506040850135614643816140d1565b91506060850135614653816140d1565b939692955090935050565b60006020828403121561467057600080fd5b5051919050565b600181811c9082168061468b57607f821691505b6020821081036146ab57634e487b7160e01b600052602260045260246000fd5b50919050565b600082601f8301126146c257600080fd5b81516146d06143dc826143a6565b8181528460208386010111156146e557600080fd5b6112fb826020830160208701614146565b80516002811061470557600080fd5b919050565b8051614705816140d1565b600060e0828403121561472757600080fd5b61472f614305565b905061473a826146f6565b8152602082015160208201526147526040830161470a565b6040820152606082015160608201526080820151608082015260a082015167ffffffffffffffff81111561478557600080fd5b614791848285016146b1565b60a08301525060c082015160c082015292915050565b600080604083850312156147ba57600080fd5b825167ffffffffffffffff808211156147d257600080fd5b9084019060c082870312156147e657600080fd5b6147ee61432e565b8251600581106147fd57600080fd5b80825250602083015160208201526040830151604082015260608301518281111561482757600080fd5b614833888286016146b1565b6060830152506080830151608082015260a083015160a082015280945050602085015191508082111561486557600080fd5b5061454b85828601614715565b6000806040838503121561488557600080fd5b8251614890816140d1565b60208401519092506145ca816140d1565b8051614705816145d5565b6000602082840312156148be57600080fd5b815167ffffffffffffffff808211156148d657600080fd5b9083019061016082860312156148eb57600080fd5b6148f3614351565b8251815260208301518281111561490957600080fd5b614915878286016146b1565b60208301525060408301518281111561492d57600080fd5b614939878286016146b1565b60408301525061494b606084016148a1565b606082015261495c608084016148a1565b608082015260a083015160a082015260c083015160c082015261498160e0840161470a565b60e0820152610100808401518381111561499a57600080fd5b6149a6888287016146b1565b8284015250506101209150818301518282015261014091506149c982840161470a565b91810191909152949350505050565b6020808252600d908201526c1058d8d95cdcc819195b9a5959609a1b604082015260600190565b60008251614a11818460208701614146565b9190910192915050565b601f821115611cf157600081815260208120601f850160051c81016020861015614a425750805b601f850160051c820191505b8181101561370c57828155600101614a4e565b815167ffffffffffffffff811115614a7b57614a7b6142ef565b614a8f81614a898454614677565b84614a1b565b602080601f831160018114614ac45760008415614aac5750858301515b600019600386901b1c1916600185901b17855561370c565b600085815260208120601f198616915b82811015614af357888601518255948401946001909101908401614ad4565b5085821015614b115787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215614bcb57600080fd5b815180151581146129e457600080fd5b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b81810381811115613f3857613f38614c0a565b80820180821115613f3857613f38614c0a565b602080825260129082015271105c989a5d1c985d1bdc881b9bdd081cd95d60721b604082015260600190565b6020808252604d908201527f446973707574652068617320616c7265616479206265656e206372656174656460408201527f206f72206265636175736520746865207472616e73616374696f6e206861732060608201526c1899595b88195e1958dd5d1959609a1b608082015260a00190565b60008154614cf281614677565b808552602060018381168015614d0f5760018114614d2957614d57565b60ff1985168884015283151560051b880183019550614d57565b866000528260002060005b85811015614d4f5781548a8201860152908301908401614d34565b890184019650505b505050505092915050565b6020815260006129e46020830184614ce5565b600281106115b1576115b161411c565b60608101614d9285614d75565b848252614d9e84614d75565b602082019390935260400152919050565b60208101614dbc83614d75565b91905290565b8281526040602082015260006129e16040830184614ce5565b600060208284031215614ded57600080fd5b81516129e4816140d1565b6020815260006129e4602083018461416a565b8082028115828204841417613f3857613f38614c0a565b600082614e3f57634e487b7160e01b600052601260045260246000fd5b500490565b8d8152602081018d9052604081018c90526001600160a01b038b81166060830152608082018b905260a082018a905260c0820189905261ffff88811660e08401528781166101008401528616610120830152841661014082015260006101a080610160840152614eb681840186614ce5565b915050826101808301529e9d5050505050505050505050505050565b60ff831681526040602082015260006129e16040830184614ce5565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b85815260a08101614f4986614d75565b60208201959095526001600160a01b03939093166040840152606083019190915260809091015291905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc73e533bc8a993eccbc1023beebad0020f6b6c3639f83062f00fc194b4d1172ba416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b69c2c919d42e5c2c9dd12ae4177551a44b8a442d59efd6afb644fcd58deae8d64736f6c63430008110033", - "deployedBytecode": "0x6080604052600436106101cd5760003560e01c80635a34257a116100f75780638b69fa0a11610095578063e308a09911610064578063e308a09914610523578063eb63612d14610543578063f2fde38b14610563578063f8c8765e1461058357600080fd5b80638b69fa0a146104a55780638da5cb5b146104c55780639dcc5daf146104e3578063ddd5e1b21461050357600080fd5b8063715018a6116100d1578063715018a6146104555780637b44cdb51461046a5780637e69b7b01461047d5780638456cb591461049057600080fd5b80635a34257a146103f45780635c975abb1461042a5780636e72b4521461044257600080fd5b80633659cfe61161016f5780633f4ba83a1161013e5780633f4ba83a1461036e5780634f1ef2861461038357806352d1902d14610396578063572b6c05146103ab57600080fd5b80633659cfe6146102ee5780633751d89c1461030e5780633a1121cd1461032e5780633ab4a6a41461034e57600080fd5b806315734fe7116101ab57806315734fe71461026b57806326d006681461027e5780632fbe3b03146102a0578063311a6c56146102ce57600080fd5b806306d6e63f146101d25780630a1a47d6146102105780630fa683d31461023e575b600080fd5b3480156101de57600080fd5b50610101546101f3906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021c57600080fd5b5061023061022b3660046140e6565b6105a3565b604051908152602001610207565b34801561024a57600080fd5b5061025e610259366004614103565b61070f565b6040516102079190614196565b61023061027936600461442c565b610a5d565b34801561028a57600080fd5b5061029e6102993660046140e6565b611303565b005b3480156102ac57600080fd5b506102306102bb366004614103565b6101026020526000908152604090205481565b3480156102da57600080fd5b5061029e6102e93660046144a3565b611366565b3480156102fa57600080fd5b5061029e6103093660046140e6565b6114d5565b34801561031a57600080fd5b5061029e6103293660046140e6565b6115b4565b34801561033a57600080fd5b5061029e6103493660046144c5565b61160d565b34801561035a57600080fd5b5061029e610369366004614103565b611716565b34801561037a57600080fd5b5061029e6118cc565b61029e6103913660046144f1565b6118de565b3480156103a257600080fd5b506102306119aa565b3480156103b757600080fd5b506103e46103c63660046140e6565b6001600160a01b031660009081526065602052604090205460ff1690565b6040519015158152602001610207565b34801561040057600080fd5b506101015461041790600160a01b900461ffff1681565b60405161ffff9091168152602001610207565b34801561043657600080fd5b5060665460ff166103e4565b61029e610450366004614103565b611a5d565b34801561046157600080fd5b5061029e611cf6565b61029e610478366004614103565b611d08565b61029e61048b366004614103565b611f82565b34801561049c57600080fd5b5061029e61203a565b3480156104b157600080fd5b5061029e6104c0366004614555565b61204a565b3480156104d157600080fd5b506033546001600160a01b03166101f3565b3480156104ef57600080fd5b5061029e6104fe3660046144c5565b6123ad565b34801561050f57600080fd5b5061029e61051e3660046145a5565b61249b565b34801561052f57600080fd5b5061029e61053e3660046140e6565b6126af565b34801561054f57600080fd5b5061029e61055e3660046145e5565b6126da565b34801561056f57600080fd5b5061029e61057e3660046140e6565b612733565b34801561058f57600080fd5b5061029e61059e366004614602565b6127a9565b6000806105ae61292a565b9050806001600160a01b03166105cc6033546001600160a01b031690565b6001600160a01b0316036106165750506001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc602052604090205490565b61010054604051631847c06b60e01b81526001600160a01b0383811660048301526000921690631847c06b90602401602060405180830381865afa158015610662573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610686919061465e565b6101005460405162f577a560e81b8152600481018390529192506001600160a01b03169063f577a5009060240160006040518083038186803b1580156106cb57600080fd5b505afa1580156106df573d6000803e3d6000fd5b50505060009182525060fd602090815260408083206001600160a01b039096168352949052929092205492915050565b6107a96040805161026081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290529061018082019081526020016000815260200160008152602001600081526020016000815260200160608152602001600081525090565b600082815260fc602090815260408083208151610260810183528154815260018201546001600160a01b039081169482019490945260028201548416928101929092526003810154831660608301526004808201546080840152600582015460a0840152600682015460c0840152600782015460e0840152600882015461ffff8082166101008601526201000082048116610120860152640100000000820416610140850152600160301b810490941661016084015291929091610180840191600160d01b900460ff16908111156108835761088361411c565b60048111156108945761089461411c565b815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d820180546108d090614677565b80601f01602080910402602001604051908101604052809291908181526020018280546108fc90614677565b80156109495780601f1061091e57610100808354040283529160200191610949565b820191906000526020600020905b81548152906001019060200180831161092c57829003601f168201915b50505050508152602001600e8201548152505090506109686101035490565b8151106109b55760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064015b60405180910390fd5b60006109bf61292a565b905081602001516001600160a01b0316816001600160a01b031614806109fa575081604001516001600160a01b0316816001600160a01b0316145b610a565760405162461bcd60e51b815260206004820152602760248201527f596f7520617265206e6f742072656c6174656420746f2074686973207472616e60448201526639b0b1ba34b7b760c91b60648201526084016109ac565b5092915050565b6000610a67612939565b60fe5460405163353bb87f60e21b8152600481018790526024810186905260009182916001600160a01b039091169063d4eee1fc90604401600060405180830381865afa158015610abc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ae491908101906147a7565b60ff54602083810151908301516040516303ef723760e61b81526004810192909252602482015292945090925060009182916001600160a01b03169063fbdc8dc0906044016040805180830381865afa158015610b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b699190614872565b6101005460a0870151604051630b7a459360e31b815260048101919091529294509092506000916001600160a01b0390911690635bd22c9890602401600060405180830381865afa158015610bc2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610bea91908101906148ac565b9050600084608001518660a0015103610c035781610c80565b610100546080860151604051630b7a459360e31b81526001600160a01b0390921691635bd22c9891610c3b9160040190815260200190565b600060405180830381865afa158015610c58573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c8091908101906148ac565b90506000610c9b86606001518460600151846080015161297f565b60408701519091506001600160a01b0316610cf957803414610cf45760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016109ac565b610d3c565b3415610d3c5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016109ac565b846001600160a01b0316610d4e61292a565b6001600160a01b031614610d745760405162461bcd60e51b81526004016109ac906149d8565b8a866020015114610dbf5760405162461bcd60e51b8152602060048201526015602482015274125b98dbdc9c9958dd081c1c9bdc1bdcd85b081251605a1b60448201526064016109ac565b428660c001511015610e065760405162461bcd60e51b815260206004820152601060248201526f141c9bdc1bdcd85b08195e1c1a5c995960821b60448201526064016109ac565b600087516004811115610e1b57610e1b61411c565b14610e685760405162461bcd60e51b815260206004820152601760248201527f5365727669636520737461747573206e6f74206f70656e00000000000000000060448201526064016109ac565b600086516001811115610e7d57610e7d61411c565b14610eca5760405162461bcd60e51b815260206004820152601b60248201527f50726f706f73616c20737461747573206e6f742070656e64696e67000000000060448201526064016109ac565b8951602e14610f095760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b60448201526064016109ac565b88604051602001610f1a91906149ff565b604051602081830303815290604052805190602001208660a00151604051602001610f4591906149ff565b6040516020818303038152906040528051906020012014610fa85760405162461bcd60e51b815260206004820152601c60248201527f50726f706f73616c206461746155726920686173206368616e6765640000000060448201526064016109ac565b6000610fb46101035490565b9050604051806102600160405280828152602001876001600160a01b03168152602001866001600160a01b0316815260200188604001516001600160a01b0316815260200188606001518152602001600081526020018e81526020018d815260200161010160149054906101000a900461ffff1661ffff168152602001856060015161ffff168152602001846080015161ffff1681526020018560e001516001600160a01b03168152602001600060048111156110735761107361411c565b8152600060208083018290526040808401839052606080850184905242608080870191909152610100808c015160a080890191909152610120808e015160c0998a01528a885260fc87529685902089518155958901516001870180546001600160a01b039283166001600160a01b031991821617909155958a01516002880180549183169188169190911790559389015160038701805491861691909616179094559087015160048086019190915592870151600585015594860151600684015560e086015160078401559385015160088301805494870151610140880151610160890151909716600160301b026601000000000000600160d01b031961ffff9889166401000000000216640100000000600160d01b0319928916620100000263ffffffff19909816989094169790971795909517949094161793909317808355610180850151919391929160ff60d01b1990911690600160d01b9084908111156111e0576111e061411c565b02179055506101a082015160098201556101c0820151600a8201556101e0820151600b820155610200820151600c820155610220820151600d8201906112269082614a61565b5061024082015181600e015590505061124461010380546001019055565b60fe546040516353eaf57560e11b8152600481018f9052602481018e9052604481018390526001600160a01b039091169063a7d5eaea90606401600060405180830381600087803b15801561129857600080fd5b505af11580156112ac573d6000803e3d6000fd5b5050505060408701516001600160a01b0316156112dd5760408701516112dd906001600160a01b03168730856129eb565b6112f188602001518860200151838e612a4b565b9750505050505050505b949350505050565b61130b612b66565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b600061137061292a565b6000848152610102602090815260408083205480845260fc909252909120600881015492935090916001600160a01b03808516600160301b90920416146114035760405162461bcd60e51b815260206004820152602160248201527f5468652063616c6c6572206d757374206265207468652061726269747261746f6044820152603960f91b60648201526084016109ac565b60036008820154600160d01b900460ff1660048111156114255761142561411c565b146114805760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652068617320616c7265616479206265656e207265736044820152641bdb1d995960da1b60648201526084016109ac565b84836001600160a01b03167f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e75622276866040516114bc91815260200190565b60405180910390a36114ce8285612bdf565b5050505050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361151d5760405162461bcd60e51b81526004016109ac90614b21565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611566600080516020614f76833981519152546001600160a01b031690565b6001600160a01b03161461158c5760405162461bcd60e51b81526004016109ac90614b6d565b61159581612e69565b604080516000808252602082019092526115b191839190612e71565b50565b6115bc612b66565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee6910161135b565b611615612939565b60ff5483906001600160a01b0316632fa117e58261163161292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561167b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169f9190614bb9565b6116bb5760405162461bcd60e51b81526004016109ac90614bdb565b6116c88360008685612fdc565b600083815260fc60205260408120600481018054919285926116eb908490614c20565b92505081905550828160050160008282546117069190614c33565b909155506114ce905084846132c7565b600081815260fc60205260409020600e810154600c8201546117389042614c20565b10156117865760405162461bcd60e51b815260206004820152601f60248201527f54696d656f75742074696d6520686173206e6f7420706173736564207965740060448201526064016109ac565b60016008820154600160d01b900460ff1660048111156117a8576117a861411c565b0361182b57600a8101541561181c57600a81018054600091829055600183015460405191926001600160a01b0390911691839181818185875af1925050503d8060008114611812576040519150601f19603f3d011682016040523d82523d6000602084013e611817565b606091505b505050505b611827826002612bdf565b5050565b60026008820154600160d01b900460ff16600481111561184d5761184d61411c565b0361182757600b810154156118c157600b81018054600091829055600283015460405191926001600160a01b0390911691839181818185875af1925050503d80600081146118b7576040519150601f19603f3d011682016040523d82523d6000602084013e6118bc565b606091505b505050505b611827826001612bdf565b6118d4612b66565b6118dc61330c565b565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036119265760405162461bcd60e51b81526004016109ac90614b21565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661196f600080516020614f76833981519152546001600160a01b031690565b6001600160a01b0316146119955760405162461bcd60e51b81526004016109ac90614b6d565b61199e82612e69565b61182782826001612e71565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a4a5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016109ac565b50600080516020614f7683398151915290565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611a9c5760405162461bcd60e51b81526004016109ac90614c46565b60036008820154600160d01b900460ff166004811115611abe57611abe61411c565b10611adb5760405162461bcd60e51b81526004016109ac90614c72565b60028101546001600160a01b0316611af161292a565b6001600160a01b031614611b475760405162461bcd60e51b815260206004820152601f60248201527f5468652063616c6c6572206d757374206265207468652072656365697665720060448201526064016109ac565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611b8490600d860190600401614d62565b602060405180830381865afa158015611ba1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc5919061465e565b90503482600b016000828254611bdb9190614c33565b9091555050600b8201548114611c525760405162461bcd60e51b815260206004820152603660248201527f54686520726563656976657220666565206d75737420626520657175616c20746044820152751bc81d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60521b60648201526084016109ac565b42600c8301556040518390600080516020614f9683398151915290611c7e906000906001903490614d85565b60405180910390a28082600a01541015611ce75760088201805460ff60d01b1916600160d01b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611cda90600090614daf565b60405180910390a2505050565b611cf18382613364565b505050565b611cfe612b66565b6118dc60006135b7565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611d475760405162461bcd60e51b81526004016109ac90614c46565b60036008820154600160d01b900460ff166004811115611d6957611d6961411c565b10611d865760405162461bcd60e51b81526004016109ac90614c72565b60018101546001600160a01b0316611d9c61292a565b6001600160a01b031614611df25760405162461bcd60e51b815260206004820152601d60248201527f5468652063616c6c6572206d757374206265207468652073656e64657200000060448201526064016109ac565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611e2f90600d860190600401614d62565b602060405180830381865afa158015611e4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e70919061465e565b90503482600a016000828254611e869190614c33565b9091555050600a8201548114611efb5760405162461bcd60e51b815260206004820152603460248201527f5468652073656e64657220666565206d75737420626520657175616c20746f206044820152731d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60621b60648201526084016109ac565b42600c8301556040518390600080516020614f9683398151915290611f269060009081903490614d85565b60405180910390a28082600b01541015611ce75760088201805460ff60d01b1916600160d11b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611cda90600190614daf565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611fc15760405162461bcd60e51b81526004016109ac90614c46565b6008810154600982015460405163093225f160e31b8152600160301b9092046001600160a01b0316916349912f889134916120049190600d870190600401614dc2565b6000604051808303818588803b15801561201d57600080fd5b505af1158015612031573d6000803e3d6000fd5b50505050505050565b612042612b66565b6118dc613609565b60ff5483906001600160a01b0316632fa117e58261206661292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156120b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d49190614bb9565b6120f05760405162461bcd60e51b81526004016109ac90614bdb565b8151602e1461212f5760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b60448201526064016109ac565b600083815260fc602052604090206008810154600160301b90046001600160a01b031661216e5760405162461bcd60e51b81526004016109ac90614c46565b60ff546040516331a9108f60e11b8152600481018790526000916001600160a01b031690636352211e90602401602060405180830381865afa1580156121b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121dc9190614ddb565b60018301549091506001600160a01b038083169116148061220c575060028201546001600160a01b038281169116145b612280576040805162461bcd60e51b81526020600482015260248101919091527f5468652063616c6c6572206d757374206265207468652073656e646572206f7260448201527f20746865207265636569766572206f722074686569722064656c65676174657360648201526084016109ac565b60046008830154600160d01b900460ff1660048111156122a2576122a261411c565b106123095760405162461bcd60e51b815260206004820152603160248201527f4d757374206e6f742073656e642065766964656e6365206966207468652064696044820152701cdc1d5d19481a5cc81c995cdbdb1d9959607a1b60648201526084016109ac565b806001600160a01b0316858360080160069054906101000a90046001600160a01b03166001600160a01b03167fdccf2f8b2cc26eafcd61905cba744cff4b81d14740725f6376390dc6298a6a3c876040516123649190614df8565b60405180910390a485857fd998ce0f89c38b0f93256f0b843a404a3a3c5055b75265623f7cb9c369a1dd628660405161239d9190614df8565b60405180910390a3505050505050565b6123b5612939565b60ff5483906001600160a01b0316632fa117e5826123d161292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561241b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243f9190614bb9565b61245b5760405162461bcd60e51b81526004016109ac90614bdb565b6124688360018685612fdc565b600083815260fc602052604081206004810180549192859261248b908490614c20565b909155506114ce90508484613647565b6124a3612939565b60006124ad61292a565b6001600160a01b03166124c86033546001600160a01b031690565b6001600160a01b0316036125075782156124f45760405162461bcd60e51b81526004016109ac906149d8565b50610101546001600160a01b03166125d4565b6101005460405162f577a560e81b8152600481018590526001600160a01b039091169063f577a5009060240160006040518083038186803b15801561254b57600080fd5b505afa15801561255f573d6000803e3d6000fd5b5050610100546040516331a9108f60e11b8152600481018790526001600160a01b039091169250636352211e9150602401602060405180830381865afa1580156125ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d19190614ddb565b90505b600083815260fd602090815260408083206001600160a01b0386168452909152902054806126375760405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b60448201526064016109ac565b600084815260fd602090815260408083206001600160a01b03871684529091528120556126658284836136ad565b60408051858152602081018390526001600160a01b038516917f2227733fc4c8a9034cb58087dcf6995128b9c0233b038b03366aaf30c92b92d6910160405180910390a250505050565b6126b7612b66565b61010180546001600160a01b0319166001600160a01b0392909216919091179055565b6126e2612b66565b610101805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f8339189e972f7fba792126e752aa8485af08710bce4a041c5bc3f9858acd71309060200161135b565b61273b612b66565b6001600160a01b0381166127a05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109ac565b6115b1816135b7565b600054610100900460ff16158080156127c95750600054600160ff909116105b806127e35750303b1580156127e3575060005460ff166001145b6128465760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016109ac565b6000805460ff191660011790558015612869576000805461ff0019166101001790555b612871613787565b6128796137b6565b60fe80546001600160a01b038088166001600160a01b03199283161790925560ff805487841690831617905561010080548684169083161790556101018054928516929091169190911790556128d461010380546001019055565b6128de60646126da565b80156114ce576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b60006129346137dd565b905090565b60665460ff16156118dc5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016109ac565b600061271061299261ffff841686614e0b565b6129a061ffff861687614e0b565b610101546129b990600160a01b900461ffff1688614e0b565b6129c39190614c33565b6129cd9190614c33565b6129d79190614e22565b6129e19085614c33565b90505b9392505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612a45908590613816565b50505050565b600060fc600084815260200190815260200160002090507f8b4f0e94aa0aee74c276abd2d92a5e2737a493b055e19d5b2d4c0ac573242a158386868460030160009054906101000a90046001600160a01b031685600401548660060154876007015461010160149054906101000a900461ffff168960080160029054906101000a900461ffff168a60080160049054906101000a900461ffff168b60080160069054906101000a90046001600160a01b03168c600d018d600e0154604051612b1f9d9c9b9a99989796959493929190614e44565b60405180910390a1827f61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d83604051612b579190614df8565b60405180910390a25050505050565b612b6e61292a565b6001600160a01b0316612b896033546001600160a01b031690565b6001600160a01b0316146118dc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ac565b600082815260fc602052604090206002821115612c2f5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c69642072756c696e6760901b60448201526064016109ac565b60018101546002820154600483018054600a85018054600b87018054600095869055928590559390935560088601805460ff60d01b1916600160d21b1790556001600160a01b0394851694909316929091906000198701612cea576040516001600160a01b038616908390600081818185875af1925050503d8060008114612cd3576040519150601f19603f3d011682016040523d82523d6000602084013e612cd8565b606091505b505050612ce58884613647565b612e25565b6001198701612d4e576040516001600160a01b038516908290600081818185875af1925050503d8060008114612d3c576040519150601f19603f3d011682016040523d82523d6000602084013e612d41565b606091505b505050612ce588846132c7565b6000612d5b600284614e22565b90506000612d6a600286614e22565b9050612d768a82613647565b612d808a826132c7565b6040516001600160a01b038816908390600081818185875af1925050503d8060008114612dc9576040519150601f19603f3d011682016040523d82523d6000602084013e612dce565b606091505b50506040516001600160a01b03881691508390600081818185875af1925050503d8060008114612e1a576040519150601f19603f3d011682016040523d82523d6000602084013e612e1f565b606091505b50505050505b877f76b363d70472d47d20e4119f3625c05ed37ca51b1d9e1cd8b87d8c20530640f388604051612e5791815260200190565b60405180910390a25050505050505050565b6115b1612b66565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612ea457611cf1836138e8565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612efe575060408051601f3d908101601f19168201909252612efb9181019061465e565b60015b612f615760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016109ac565b600080516020614f768339815191528114612fd05760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016109ac565b50611cf1838383613984565b600084815260fc6020526040812090846001811115612ffd57612ffd61411c565b036130a35760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa15801561304b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306f9190614ddb565b60018201546001600160a01b0390811691161461309e5760405162461bcd60e51b81526004016109ac906149d8565b613158565b60018460018111156130b7576130b761411c565b036131585760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa158015613105573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131299190614ddb565b60028201546001600160a01b039081169116146131585760405162461bcd60e51b81526004016109ac906149d8565b610103548154106131a45760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064016109ac565b60006008820154600160d01b900460ff1660048111156131c6576131c661411c565b146132215760405162461bcd60e51b815260206004820152602560248201527f546865207472616e73616374696f6e2073686f756c646e2774206265206469736044820152641c1d5d195960da1b60648201526084016109ac565b818160040154101561326a5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b60448201526064016109ac565b6127108210158061328a57506127108210801561328a5750806004015482145b6114ce5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016109ac565b6132d182826139a9565b600082815260fc6020526040902060028101546003820154613300916001600160a01b039081169116846136ad565b611cf183600084613c57565b613314613d79565b6066805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61334761292a565b6040516001600160a01b03909116815260200160405180910390a1565b600082815260fc60205260409081902060088101805460ff60d01b1916600360d01b1790819055915163c13517e160e01b81529091600160301b90046001600160a01b031690819063c13517e19085906133c890600290600d880190600401614ed2565b60206040518083038185885af11580156133e6573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061340b919061465e565b600983018181556000918252610102602090815260409283902087905590548251878152918201879052916001600160a01b038416917f74baab670a4015ab2f1b467c5252a96141a2573f2908e58a92081e80d3cfde3d910160405180910390a38282600a015411156135175760008383600a015461348a9190614c20565b600a840185905560018401546040519192506001600160a01b0316908290600081818185875af1925050503d80600081146134e1576040519150601f19603f3d011682016040523d82523d6000602084013e6134e6565b606091505b50505084600080516020614f96833981519152600160003460405161350d93929190614d85565b60405180910390a2505b8282600b01541115612a455760008383600b01546135359190614c20565b600b840185905560028401546040519192506001600160a01b0316908290600081818185875af1925050503d806000811461358c576040519150601f19603f3d011682016040523d82523d6000602084013e613591565b606091505b50505084600080516020614f9683398151915260018034604051612b5793929190614d85565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b613611612939565b6066805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861334761292a565b600082815260fc60205260408120600881015490919061367d90849061ffff62010000820481169164010000000090041661297f565b600183015460038401549192506136a1916001600160a01b039182169116836136ad565b612a4584600185613c57565b6001600160a01b038216600003613714576040516001600160a01b038416908290600081818185875af1925050503d8060008114613707576040519150601f19603f3d011682016040523d82523d6000602084013e61370c565b606091505b505050505050565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb906044016020604051808303816000875af1158015613763573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a459190614bb9565b600054610100900460ff166137ae5760405162461bcd60e51b81526004016109ac90614eee565b6118dc613dc2565b600054610100900460ff166118dc5760405162461bcd60e51b81526004016109ac90614eee565b6000601436108015906137ff57503360009081526065602052604090205460ff165b15613811575060131936013560601c90565b503390565b600061386b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613df99092919063ffffffff16565b805190915015611cf157808060200190518101906138899190614bb9565b611cf15760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109ac565b6001600160a01b0381163b6139555760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016109ac565b600080516020614f7683398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61398d83613e08565b60008251118061399a5750805b15611cf157612a458383613e48565b600082815260fc602052604080822060fe5460068201546007830154935163353bb87f60e21b81526004810191909152602481019390935290929182916001600160a01b03169063d4eee1fc90604401600060405180830381865afa158015613a16573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613a3e91908101906147a7565b60a0820151608082015160088701549395509193509160009061271090613a6a90899061ffff16614e0b565b613a749190614e22565b600887015490915060009061271090613a98908a9062010000900461ffff16614e0b565b613aa29190614e22565b600888015490915060009061271090613ac8908b90640100000000900461ffff16614e0b565b613ad29190614e22565b60038901546001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc6020526040812080549293508592909190613b22908490614c33565b9091555050600085815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054849290613b5d908490614c33565b9091555050600084815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054839290613b98908490614c33565b90915550506003880154600689015460408051888152602081019290925281018490526001600160a01b03909116907f17c48ab8e1617182f35ae77fd7da7f4e15dedf7018aa371a4481c20c790b65469060600160405180910390a26003880154600689015460408051878152602081019290925281018490526001600160a01b03909116907f3476ed3eea2cdac584273bc8830824c8ca42ca2a99e9f144a87a1cdbbf9dd15a9060600160405180910390a250505050505050505050565b600083815260fc602052604090819020805460038201546006830154935192937f2ab2a30b19f7bc6e386d4ee60aa21ed23c127ce9fe26903da97edd54bad0375a93613cb4939288926001600160a01b0390911691889190614f39565b60405180910390a18060040154600003612a455760fe5460068201546005830154604051635ab9ae0f60e11b8152600481019290925260248201526001600160a01b039091169063b5735c1e90604401600060405180830381600087803b158015613d1e57600080fd5b505af1158015613d32573d6000803e3d6000fd5b505050507f6bef1b5e95b741d6e665eb9b5c2d3e1203c46a771451055a9d41e0b8ff4510b78160060154604051613d6b91815260200190565b60405180910390a150505050565b60665460ff166118dc5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016109ac565b600054610100900460ff16613de95760405162461bcd60e51b81526004016109ac90614eee565b6118dc613df461292a565b6135b7565b60606129e18484600085613f3e565b613e11816138e8565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b613eb05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016109ac565b600080846001600160a01b031684604051613ecb91906149ff565b600060405180830381855af49150503d8060008114613f06576040519150601f19603f3d011682016040523d82523d6000602084013e613f0b565b606091505b5091509150613f338282604051806060016040528060278152602001614fb660279139614019565b925050505b92915050565b606082471015613f9f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016109ac565b600080866001600160a01b03168587604051613fbb91906149ff565b60006040518083038185875af1925050503d8060008114613ff8576040519150601f19603f3d011682016040523d82523d6000602084013e613ffd565b606091505b509150915061400e87838387614032565b979650505050505050565b606083156140285750816129e4565b6129e483836140a7565b606083156140a157825160000361409a576001600160a01b0385163b61409a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109ac565b50816112fb565b6112fb83835b8151156140b75781518083602001fd5b8060405162461bcd60e51b81526004016109ac9190614df8565b6001600160a01b03811681146115b157600080fd5b6000602082840312156140f857600080fd5b81356129e4816140d1565b60006020828403121561411557600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b600581106141425761414261411c565b9052565b60005b83811015614161578181015183820152602001614149565b50506000910152565b60008151808452614182816020860160208601614146565b601f01601f19169290920160200192915050565b6020815281516020820152600060208301516141bd60408401826001600160a01b03169052565b5060408301516001600160a01b03811660608401525060608301516001600160a01b038116608084015250608083015160a083015260a083015160c083015260c083015160e083015260e083015161010081818501528085015191505061012061422c8185018361ffff169052565b84015190506101406142438482018361ffff169052565b840151905061016061425a8482018361ffff169052565b8401519050610180614276848201836001600160a01b03169052565b84015190506101a061428a84820183614132565b8401516101c0848101919091528401516101e0808501919091528401516102008085019190915284015161022080850191909152840151610260610240808601829052919250906142df61028086018461416a565b9501519301929092525090919050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff81118282101715614328576143286142ef565b60405290565b60405160c0810167ffffffffffffffff81118282101715614328576143286142ef565b604051610160810167ffffffffffffffff81118282101715614328576143286142ef565b604051601f8201601f1916810167ffffffffffffffff8111828210171561439e5761439e6142ef565b604052919050565b600067ffffffffffffffff8211156143c0576143c06142ef565b50601f01601f191660200190565b60006143e16143dc846143a6565b614375565b90508281528383830111156143f557600080fd5b828260208301376000602084830101529392505050565b600082601f83011261441d57600080fd5b6129e4838335602085016143ce565b6000806000806080858703121561444257600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561446857600080fd5b6144748883890161440c565b9350606087013591508082111561448a57600080fd5b506144978782880161440c565b91505092959194509250565b600080604083850312156144b657600080fd5b50508035926020909101359150565b6000806000606084860312156144da57600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561450457600080fd5b823561450f816140d1565b9150602083013567ffffffffffffffff81111561452b57600080fd5b8301601f8101851361453c57600080fd5b61454b858235602084016143ce565b9150509250929050565b60008060006060848603121561456a57600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561458f57600080fd5b61459b8682870161440c565b9150509250925092565b600080604083850312156145b857600080fd5b8235915060208301356145ca816140d1565b809150509250929050565b61ffff811681146115b157600080fd5b6000602082840312156145f757600080fd5b81356129e4816145d5565b6000806000806080858703121561461857600080fd5b8435614623816140d1565b93506020850135614633816140d1565b92506040850135614643816140d1565b91506060850135614653816140d1565b939692955090935050565b60006020828403121561467057600080fd5b5051919050565b600181811c9082168061468b57607f821691505b6020821081036146ab57634e487b7160e01b600052602260045260246000fd5b50919050565b600082601f8301126146c257600080fd5b81516146d06143dc826143a6565b8181528460208386010111156146e557600080fd5b6112fb826020830160208701614146565b80516002811061470557600080fd5b919050565b8051614705816140d1565b600060e0828403121561472757600080fd5b61472f614305565b905061473a826146f6565b8152602082015160208201526147526040830161470a565b6040820152606082015160608201526080820151608082015260a082015167ffffffffffffffff81111561478557600080fd5b614791848285016146b1565b60a08301525060c082015160c082015292915050565b600080604083850312156147ba57600080fd5b825167ffffffffffffffff808211156147d257600080fd5b9084019060c082870312156147e657600080fd5b6147ee61432e565b8251600581106147fd57600080fd5b80825250602083015160208201526040830151604082015260608301518281111561482757600080fd5b614833888286016146b1565b6060830152506080830151608082015260a083015160a082015280945050602085015191508082111561486557600080fd5b5061454b85828601614715565b6000806040838503121561488557600080fd5b8251614890816140d1565b60208401519092506145ca816140d1565b8051614705816145d5565b6000602082840312156148be57600080fd5b815167ffffffffffffffff808211156148d657600080fd5b9083019061016082860312156148eb57600080fd5b6148f3614351565b8251815260208301518281111561490957600080fd5b614915878286016146b1565b60208301525060408301518281111561492d57600080fd5b614939878286016146b1565b60408301525061494b606084016148a1565b606082015261495c608084016148a1565b608082015260a083015160a082015260c083015160c082015261498160e0840161470a565b60e0820152610100808401518381111561499a57600080fd5b6149a6888287016146b1565b8284015250506101209150818301518282015261014091506149c982840161470a565b91810191909152949350505050565b6020808252600d908201526c1058d8d95cdcc819195b9a5959609a1b604082015260600190565b60008251614a11818460208701614146565b9190910192915050565b601f821115611cf157600081815260208120601f850160051c81016020861015614a425750805b601f850160051c820191505b8181101561370c57828155600101614a4e565b815167ffffffffffffffff811115614a7b57614a7b6142ef565b614a8f81614a898454614677565b84614a1b565b602080601f831160018114614ac45760008415614aac5750858301515b600019600386901b1c1916600185901b17855561370c565b600085815260208120601f198616915b82811015614af357888601518255948401946001909101908401614ad4565b5085821015614b115787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215614bcb57600080fd5b815180151581146129e457600080fd5b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b81810381811115613f3857613f38614c0a565b80820180821115613f3857613f38614c0a565b602080825260129082015271105c989a5d1c985d1bdc881b9bdd081cd95d60721b604082015260600190565b6020808252604d908201527f446973707574652068617320616c7265616479206265656e206372656174656460408201527f206f72206265636175736520746865207472616e73616374696f6e206861732060608201526c1899595b88195e1958dd5d1959609a1b608082015260a00190565b60008154614cf281614677565b808552602060018381168015614d0f5760018114614d2957614d57565b60ff1985168884015283151560051b880183019550614d57565b866000528260002060005b85811015614d4f5781548a8201860152908301908401614d34565b890184019650505b505050505092915050565b6020815260006129e46020830184614ce5565b600281106115b1576115b161411c565b60608101614d9285614d75565b848252614d9e84614d75565b602082019390935260400152919050565b60208101614dbc83614d75565b91905290565b8281526040602082015260006129e16040830184614ce5565b600060208284031215614ded57600080fd5b81516129e4816140d1565b6020815260006129e4602083018461416a565b8082028115828204841417613f3857613f38614c0a565b600082614e3f57634e487b7160e01b600052601260045260246000fd5b500490565b8d8152602081018d9052604081018c90526001600160a01b038b81166060830152608082018b905260a082018a905260c0820189905261ffff88811660e08401528781166101008401528616610120830152841661014082015260006101a080610160840152614eb681840186614ce5565b915050826101808301529e9d5050505050505050505050505050565b60ff831681526040602082015260006129e16040830184614ce5565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b85815260a08101614f4986614d75565b60208201959095526001600160a01b03939093166040840152606083019190915260809091015291905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc73e533bc8a993eccbc1023beebad0020f6b6c3639f83062f00fc194b4d1172ba416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b69c2c919d42e5c2c9dd12ae4177551a44b8a442d59efd6afb644fcd58deae8d64736f6c63430008110033", + "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b60805161501b62000120600039600081816114df0152818161151f015281816118e80152818161192801526119b7015261501b6000f3fe6080604052600436106101cd5760003560e01c80635a34257a116100f75780638b69fa0a11610095578063e308a09911610064578063e308a09914610523578063eb63612d14610543578063f2fde38b14610563578063f8c8765e1461058357600080fd5b80638b69fa0a146104a55780638da5cb5b146104c55780639dcc5daf146104e3578063ddd5e1b21461050357600080fd5b8063715018a6116100d1578063715018a6146104555780637b44cdb51461046a5780637e69b7b01461047d5780638456cb591461049057600080fd5b80635a34257a146103f45780635c975abb1461042a5780636e72b4521461044257600080fd5b80633659cfe61161016f5780633f4ba83a1161013e5780633f4ba83a1461036e5780634f1ef2861461038357806352d1902d14610396578063572b6c05146103ab57600080fd5b80633659cfe6146102ee5780633751d89c1461030e5780633a1121cd1461032e5780633ab4a6a41461034e57600080fd5b806315734fe7116101ab57806315734fe71461026b57806326d006681461027e5780632fbe3b03146102a0578063311a6c56146102ce57600080fd5b806306d6e63f146101d25780630a1a47d6146102105780630fa683d31461023e575b600080fd5b3480156101de57600080fd5b50610101546101f3906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021c57600080fd5b5061023061022b3660046140ea565b6105a3565b604051908152602001610207565b34801561024a57600080fd5b5061025e610259366004614107565b61070f565b604051610207919061419a565b610230610279366004614430565b610a5d565b34801561028a57600080fd5b5061029e6102993660046140ea565b611303565b005b3480156102ac57600080fd5b506102306102bb366004614107565b6101026020526000908152604090205481565b3480156102da57600080fd5b5061029e6102e93660046144a7565b611366565b3480156102fa57600080fd5b5061029e6103093660046140ea565b6114d5565b34801561031a57600080fd5b5061029e6103293660046140ea565b6115b4565b34801561033a57600080fd5b5061029e6103493660046144c9565b61160d565b34801561035a57600080fd5b5061029e610369366004614107565b611716565b34801561037a57600080fd5b5061029e6118cc565b61029e6103913660046144f5565b6118de565b3480156103a257600080fd5b506102306119aa565b3480156103b757600080fd5b506103e46103c63660046140ea565b6001600160a01b031660009081526065602052604090205460ff1690565b6040519015158152602001610207565b34801561040057600080fd5b506101015461041790600160a01b900461ffff1681565b60405161ffff9091168152602001610207565b34801561043657600080fd5b5060665460ff166103e4565b61029e610450366004614107565b611a5d565b34801561046157600080fd5b5061029e611cf6565b61029e610478366004614107565b611d08565b61029e61048b366004614107565b611f82565b34801561049c57600080fd5b5061029e61203a565b3480156104b157600080fd5b5061029e6104c0366004614559565b61204a565b3480156104d157600080fd5b506033546001600160a01b03166101f3565b3480156104ef57600080fd5b5061029e6104fe3660046144c9565b6123ad565b34801561050f57600080fd5b5061029e61051e3660046145a9565b61249b565b34801561052f57600080fd5b5061029e61053e3660046140ea565b6126af565b34801561054f57600080fd5b5061029e61055e3660046145e9565b6126da565b34801561056f57600080fd5b5061029e61057e3660046140ea565b612733565b34801561058f57600080fd5b5061029e61059e366004614606565b6127a9565b6000806105ae61292a565b9050806001600160a01b03166105cc6033546001600160a01b031690565b6001600160a01b0316036106165750506001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc602052604090205490565b61010054604051631847c06b60e01b81526001600160a01b0383811660048301526000921690631847c06b90602401602060405180830381865afa158015610662573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106869190614662565b6101005460405162f577a560e81b8152600481018390529192506001600160a01b03169063f577a5009060240160006040518083038186803b1580156106cb57600080fd5b505afa1580156106df573d6000803e3d6000fd5b50505060009182525060fd602090815260408083206001600160a01b039096168352949052929092205492915050565b6107a96040805161026081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290529061018082019081526020016000815260200160008152602001600081526020016000815260200160608152602001600081525090565b600082815260fc602090815260408083208151610260810183528154815260018201546001600160a01b039081169482019490945260028201548416928101929092526003810154831660608301526004808201546080840152600582015460a0840152600682015460c0840152600782015460e0840152600882015461ffff8082166101008601526201000082048116610120860152640100000000820416610140850152600160301b810490941661016084015291929091610180840191600160d01b900460ff169081111561088357610883614120565b600481111561089457610894614120565b815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d820180546108d09061467b565b80601f01602080910402602001604051908101604052809291908181526020018280546108fc9061467b565b80156109495780601f1061091e57610100808354040283529160200191610949565b820191906000526020600020905b81548152906001019060200180831161092c57829003601f168201915b50505050508152602001600e8201548152505090506109686101035490565b8151106109b55760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064015b60405180910390fd5b60006109bf61292a565b905081602001516001600160a01b0316816001600160a01b031614806109fa575081604001516001600160a01b0316816001600160a01b0316145b610a565760405162461bcd60e51b815260206004820152602760248201527f596f7520617265206e6f742072656c6174656420746f2074686973207472616e60448201526639b0b1ba34b7b760c91b60648201526084016109ac565b5092915050565b6000610a67612939565b60fe5460405163353bb87f60e21b8152600481018790526024810186905260009182916001600160a01b039091169063d4eee1fc90604401600060405180830381865afa158015610abc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ae491908101906147ab565b60ff54602083810151908301516040516303ef723760e61b81526004810192909252602482015292945090925060009182916001600160a01b03169063fbdc8dc0906044016040805180830381865afa158015610b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b699190614876565b6101005460a0870151604051630b7a459360e31b815260048101919091529294509092506000916001600160a01b0390911690635bd22c9890602401600060405180830381865afa158015610bc2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610bea91908101906148b0565b9050600084608001518660a0015103610c035781610c80565b610100546080860151604051630b7a459360e31b81526001600160a01b0390921691635bd22c9891610c3b9160040190815260200190565b600060405180830381865afa158015610c58573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c8091908101906148b0565b90506000610c9b86606001518460600151846080015161297f565b60408701519091506001600160a01b0316610cf957803414610cf45760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016109ac565b610d3c565b3415610d3c5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016109ac565b846001600160a01b0316610d4e61292a565b6001600160a01b031614610d745760405162461bcd60e51b81526004016109ac906149dc565b8a866020015114610dbf5760405162461bcd60e51b8152602060048201526015602482015274125b98dbdc9c9958dd081c1c9bdc1bdcd85b081251605a1b60448201526064016109ac565b428660c001511015610e065760405162461bcd60e51b815260206004820152601060248201526f141c9bdc1bdcd85b08195e1c1a5c995960821b60448201526064016109ac565b600087516004811115610e1b57610e1b614120565b14610e685760405162461bcd60e51b815260206004820152601760248201527f5365727669636520737461747573206e6f74206f70656e00000000000000000060448201526064016109ac565b600086516001811115610e7d57610e7d614120565b14610eca5760405162461bcd60e51b815260206004820152601b60248201527f50726f706f73616c20737461747573206e6f742070656e64696e67000000000060448201526064016109ac565b8951602e14610f095760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b60448201526064016109ac565b88604051602001610f1a9190614a03565b604051602081830303815290604052805190602001208660a00151604051602001610f459190614a03565b6040516020818303038152906040528051906020012014610fa85760405162461bcd60e51b815260206004820152601c60248201527f50726f706f73616c206461746155726920686173206368616e6765640000000060448201526064016109ac565b6000610fb46101035490565b9050604051806102600160405280828152602001876001600160a01b03168152602001866001600160a01b0316815260200188604001516001600160a01b0316815260200188606001518152602001600081526020018e81526020018d815260200161010160149054906101000a900461ffff1661ffff168152602001856060015161ffff168152602001846080015161ffff1681526020018560e001516001600160a01b031681526020016000600481111561107357611073614120565b8152600060208083018290526040808401839052606080850184905242608080870191909152610100808c015160a080890191909152610120808e015160c0998a01528a885260fc87529685902089518155958901516001870180546001600160a01b039283166001600160a01b031991821617909155958a01516002880180549183169188169190911790559389015160038701805491861691909616179094559087015160048086019190915592870151600585015594860151600684015560e086015160078401559385015160088301805494870151610140880151610160890151909716600160301b026601000000000000600160d01b031961ffff9889166401000000000216640100000000600160d01b0319928916620100000263ffffffff19909816989094169790971795909517949094161793909317808355610180850151919391929160ff60d01b1990911690600160d01b9084908111156111e0576111e0614120565b02179055506101a082015160098201556101c0820151600a8201556101e0820151600b820155610200820151600c820155610220820151600d8201906112269082614a65565b5061024082015181600e015590505061124461010380546001019055565b60fe546040516353eaf57560e11b8152600481018f9052602481018e9052604481018390526001600160a01b039091169063a7d5eaea90606401600060405180830381600087803b15801561129857600080fd5b505af11580156112ac573d6000803e3d6000fd5b5050505060408701516001600160a01b0316156112dd5760408701516112dd906001600160a01b03168730856129eb565b6112f188602001518860200151838e612a4b565b9750505050505050505b949350505050565b61130b612b66565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b600061137061292a565b6000848152610102602090815260408083205480845260fc909252909120600881015492935090916001600160a01b03808516600160301b90920416146114035760405162461bcd60e51b815260206004820152602160248201527f5468652063616c6c6572206d757374206265207468652061726269747261746f6044820152603960f91b60648201526084016109ac565b60036008820154600160d01b900460ff16600481111561142557611425614120565b146114805760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652068617320616c7265616479206265656e207265736044820152641bdb1d995960da1b60648201526084016109ac565b84836001600160a01b03167f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e75622276866040516114bc91815260200190565b60405180910390a36114ce8285612bdf565b5050505050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361151d5760405162461bcd60e51b81526004016109ac90614b25565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611566600080516020614f7f833981519152546001600160a01b031690565b6001600160a01b03161461158c5760405162461bcd60e51b81526004016109ac90614b71565b61159581612e69565b604080516000808252602082019092526115b191839190612e71565b50565b6115bc612b66565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee6910161135b565b611615612939565b60ff5483906001600160a01b0316632fa117e58261163161292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561167b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169f9190614bbd565b6116bb5760405162461bcd60e51b81526004016109ac90614bdf565b6116c88360008685612fdc565b600083815260fc60205260408120600481018054919285926116eb908490614c24565b92505081905550828160050160008282546117069190614c37565b909155506114ce905084846132c7565b600081815260fc60205260409020600e810154600c8201546117389042614c24565b10156117865760405162461bcd60e51b815260206004820152601f60248201527f54696d656f75742074696d6520686173206e6f7420706173736564207965740060448201526064016109ac565b60016008820154600160d01b900460ff1660048111156117a8576117a8614120565b0361182b57600a8101541561181c57600a81018054600091829055600183015460405191926001600160a01b0390911691839181818185875af1925050503d8060008114611812576040519150601f19603f3d011682016040523d82523d6000602084013e611817565b606091505b505050505b611827826002612bdf565b5050565b60026008820154600160d01b900460ff16600481111561184d5761184d614120565b0361182757600b810154156118c157600b81018054600091829055600283015460405191926001600160a01b0390911691839181818185875af1925050503d80600081146118b7576040519150601f19603f3d011682016040523d82523d6000602084013e6118bc565b606091505b505050505b611827826001612bdf565b6118d4612b66565b6118dc61330c565b565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036119265760405162461bcd60e51b81526004016109ac90614b25565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661196f600080516020614f7f833981519152546001600160a01b031690565b6001600160a01b0316146119955760405162461bcd60e51b81526004016109ac90614b71565b61199e82612e69565b61182782826001612e71565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a4a5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016109ac565b50600080516020614f7f83398151915290565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611a9c5760405162461bcd60e51b81526004016109ac90614c4a565b60036008820154600160d01b900460ff166004811115611abe57611abe614120565b10611adb5760405162461bcd60e51b81526004016109ac90614c76565b60028101546001600160a01b0316611af161292a565b6001600160a01b031614611b475760405162461bcd60e51b815260206004820152601f60248201527f5468652063616c6c6572206d757374206265207468652072656365697665720060448201526064016109ac565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611b8490600d860190600401614d66565b602060405180830381865afa158015611ba1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc59190614662565b90503482600b016000828254611bdb9190614c37565b9091555050600b8201548114611c525760405162461bcd60e51b815260206004820152603660248201527f54686520726563656976657220666565206d75737420626520657175616c20746044820152751bc81d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60521b60648201526084016109ac565b42600c8301556040518390600080516020614f9f83398151915290611c7e906000906001903490614d89565b60405180910390a28082600a01541015611ce75760088201805460ff60d01b1916600160d01b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611cda90600090614db3565b60405180910390a2505050565b611cf18382613364565b505050565b611cfe612b66565b6118dc60006135b7565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611d475760405162461bcd60e51b81526004016109ac90614c4a565b60036008820154600160d01b900460ff166004811115611d6957611d69614120565b10611d865760405162461bcd60e51b81526004016109ac90614c76565b60018101546001600160a01b0316611d9c61292a565b6001600160a01b031614611df25760405162461bcd60e51b815260206004820152601d60248201527f5468652063616c6c6572206d757374206265207468652073656e64657200000060448201526064016109ac565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611e2f90600d860190600401614d66565b602060405180830381865afa158015611e4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e709190614662565b90503482600a016000828254611e869190614c37565b9091555050600a8201548114611efb5760405162461bcd60e51b815260206004820152603460248201527f5468652073656e64657220666565206d75737420626520657175616c20746f206044820152731d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60621b60648201526084016109ac565b42600c8301556040518390600080516020614f9f83398151915290611f269060009081903490614d89565b60405180910390a28082600b01541015611ce75760088201805460ff60d01b1916600160d11b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611cda90600190614db3565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611fc15760405162461bcd60e51b81526004016109ac90614c4a565b6008810154600982015460405163093225f160e31b8152600160301b9092046001600160a01b0316916349912f889134916120049190600d870190600401614dc6565b6000604051808303818588803b15801561201d57600080fd5b505af1158015612031573d6000803e3d6000fd5b50505050505050565b612042612b66565b6118dc613609565b60ff5483906001600160a01b0316632fa117e58261206661292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156120b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d49190614bbd565b6120f05760405162461bcd60e51b81526004016109ac90614bdf565b8151602e1461212f5760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b60448201526064016109ac565b600083815260fc602052604090206008810154600160301b90046001600160a01b031661216e5760405162461bcd60e51b81526004016109ac90614c4a565b60ff546040516331a9108f60e11b8152600481018790526000916001600160a01b031690636352211e90602401602060405180830381865afa1580156121b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121dc9190614ddf565b60018301549091506001600160a01b038083169116148061220c575060028201546001600160a01b038281169116145b612280576040805162461bcd60e51b81526020600482015260248101919091527f5468652063616c6c6572206d757374206265207468652073656e646572206f7260448201527f20746865207265636569766572206f722074686569722064656c65676174657360648201526084016109ac565b60046008830154600160d01b900460ff1660048111156122a2576122a2614120565b106123095760405162461bcd60e51b815260206004820152603160248201527f4d757374206e6f742073656e642065766964656e6365206966207468652064696044820152701cdc1d5d19481a5cc81c995cdbdb1d9959607a1b60648201526084016109ac565b806001600160a01b0316858360080160069054906101000a90046001600160a01b03166001600160a01b03167fdccf2f8b2cc26eafcd61905cba744cff4b81d14740725f6376390dc6298a6a3c876040516123649190614dfc565b60405180910390a485857fd998ce0f89c38b0f93256f0b843a404a3a3c5055b75265623f7cb9c369a1dd628660405161239d9190614dfc565b60405180910390a3505050505050565b6123b5612939565b60ff5483906001600160a01b0316632fa117e5826123d161292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561241b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243f9190614bbd565b61245b5760405162461bcd60e51b81526004016109ac90614bdf565b6124688360018685612fdc565b600083815260fc602052604081206004810180549192859261248b908490614c24565b909155506114ce90508484613647565b6124a3612939565b60006124ad61292a565b6001600160a01b03166124c86033546001600160a01b031690565b6001600160a01b0316036125075782156124f45760405162461bcd60e51b81526004016109ac906149dc565b50610101546001600160a01b03166125d4565b6101005460405162f577a560e81b8152600481018590526001600160a01b039091169063f577a5009060240160006040518083038186803b15801561254b57600080fd5b505afa15801561255f573d6000803e3d6000fd5b5050610100546040516331a9108f60e11b8152600481018790526001600160a01b039091169250636352211e9150602401602060405180830381865afa1580156125ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d19190614ddf565b90505b600083815260fd602090815260408083206001600160a01b0386168452909152902054806126375760405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b60448201526064016109ac565b600084815260fd602090815260408083206001600160a01b03871684529091528120556126658284836136ad565b60408051858152602081018390526001600160a01b038516917f2227733fc4c8a9034cb58087dcf6995128b9c0233b038b03366aaf30c92b92d6910160405180910390a250505050565b6126b7612b66565b61010180546001600160a01b0319166001600160a01b0392909216919091179055565b6126e2612b66565b610101805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f8339189e972f7fba792126e752aa8485af08710bce4a041c5bc3f9858acd71309060200161135b565b61273b612b66565b6001600160a01b0381166127a05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109ac565b6115b1816135b7565b600054610100900460ff16158080156127c95750600054600160ff909116105b806127e35750303b1580156127e3575060005460ff166001145b6128465760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016109ac565b6000805460ff191660011790558015612869576000805461ff0019166101001790555b612871613787565b6128796137b6565b60fe80546001600160a01b038088166001600160a01b03199283161790925560ff805487841690831617905561010080548684169083161790556101018054928516929091169190911790556128d461010380546001019055565b6128de60646126da565b80156114ce576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b60006129346137dd565b905090565b60665460ff16156118dc5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016109ac565b600061271061299261ffff841686614e0f565b6129a061ffff861687614e0f565b610101546129b990600160a01b900461ffff1688614e0f565b6129c39190614c37565b6129cd9190614c37565b6129d79190614e26565b6129e19085614c37565b90505b9392505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612a45908590613816565b50505050565b600060fc600084815260200190815260200160002090507f8b4f0e94aa0aee74c276abd2d92a5e2737a493b055e19d5b2d4c0ac573242a158386868460030160009054906101000a90046001600160a01b031685600401548660060154876007015461010160149054906101000a900461ffff168960080160029054906101000a900461ffff168a60080160049054906101000a900461ffff168b60080160069054906101000a90046001600160a01b03168c600d018d600e0154604051612b1f9d9c9b9a99989796959493929190614e48565b60405180910390a1827f61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d83604051612b579190614dfc565b60405180910390a25050505050565b612b6e61292a565b6001600160a01b0316612b896033546001600160a01b031690565b6001600160a01b0316146118dc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ac565b600082815260fc602052604090206002821115612c2f5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c69642072756c696e6760901b60448201526064016109ac565b60018101546002820154600483018054600a85018054600b87018054600095869055928590559390935560088601805460ff60d01b1916600160d21b1790556001600160a01b0394851694909316929091906000198701612cea576040516001600160a01b038616908390600081818185875af1925050503d8060008114612cd3576040519150601f19603f3d011682016040523d82523d6000602084013e612cd8565b606091505b505050612ce58884613647565b612e25565b6001198701612d4e576040516001600160a01b038516908290600081818185875af1925050503d8060008114612d3c576040519150601f19603f3d011682016040523d82523d6000602084013e612d41565b606091505b505050612ce588846132c7565b6000612d5b600284614e26565b90506000612d6a600286614e26565b9050612d768a82613647565b612d808a826132c7565b6040516001600160a01b038816908390600081818185875af1925050503d8060008114612dc9576040519150601f19603f3d011682016040523d82523d6000602084013e612dce565b606091505b50506040516001600160a01b03881691508390600081818185875af1925050503d8060008114612e1a576040519150601f19603f3d011682016040523d82523d6000602084013e612e1f565b606091505b50505050505b877f76b363d70472d47d20e4119f3625c05ed37ca51b1d9e1cd8b87d8c20530640f388604051612e5791815260200190565b60405180910390a25050505050505050565b6115b1612b66565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612ea457611cf1836138e8565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612efe575060408051601f3d908101601f19168201909252612efb91810190614662565b60015b612f615760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016109ac565b600080516020614f7f8339815191528114612fd05760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016109ac565b50611cf1838383613984565b600084815260fc6020526040812090846001811115612ffd57612ffd614120565b036130a35760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa15801561304b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306f9190614ddf565b60018201546001600160a01b0390811691161461309e5760405162461bcd60e51b81526004016109ac906149dc565b613158565b60018460018111156130b7576130b7614120565b036131585760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa158015613105573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131299190614ddf565b60028201546001600160a01b039081169116146131585760405162461bcd60e51b81526004016109ac906149dc565b610103548154106131a45760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064016109ac565b60006008820154600160d01b900460ff1660048111156131c6576131c6614120565b146132215760405162461bcd60e51b815260206004820152602560248201527f546865207472616e73616374696f6e2073686f756c646e2774206265206469736044820152641c1d5d195960da1b60648201526084016109ac565b818160040154101561326a5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b60448201526064016109ac565b6127108210158061328a57506127108210801561328a5750806004015482145b6114ce5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016109ac565b6132d182826139a9565b600082815260fc6020526040902060028101546003820154613300916001600160a01b039081169116846136ad565b611cf183600084613c57565b613314613d7d565b6066805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61334761292a565b6040516001600160a01b03909116815260200160405180910390a1565b600082815260fc60205260409081902060088101805460ff60d01b1916600360d01b1790819055915163c13517e160e01b81529091600160301b90046001600160a01b031690819063c13517e19085906133c890600290600d880190600401614ed6565b60206040518083038185885af11580156133e6573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061340b9190614662565b600983018181556000918252610102602090815260409283902087905590548251878152918201879052916001600160a01b038416917f74baab670a4015ab2f1b467c5252a96141a2573f2908e58a92081e80d3cfde3d910160405180910390a38282600a015411156135175760008383600a015461348a9190614c24565b600a840185905560018401546040519192506001600160a01b0316908290600081818185875af1925050503d80600081146134e1576040519150601f19603f3d011682016040523d82523d6000602084013e6134e6565b606091505b50505084600080516020614f9f833981519152600160003460405161350d93929190614d89565b60405180910390a2505b8282600b01541115612a455760008383600b01546135359190614c24565b600b840185905560028401546040519192506001600160a01b0316908290600081818185875af1925050503d806000811461358c576040519150601f19603f3d011682016040523d82523d6000602084013e613591565b606091505b50505084600080516020614f9f83398151915260018034604051612b5793929190614d89565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b613611612939565b6066805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861334761292a565b600082815260fc60205260408120600881015490919061367d90849061ffff62010000820481169164010000000090041661297f565b600183015460038401549192506136a1916001600160a01b039182169116836136ad565b612a4584600185613c57565b6001600160a01b038216600003613714576040516001600160a01b038416908290600081818185875af1925050503d8060008114613707576040519150601f19603f3d011682016040523d82523d6000602084013e61370c565b606091505b505050505050565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb906044016020604051808303816000875af1158015613763573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a459190614bbd565b600054610100900460ff166137ae5760405162461bcd60e51b81526004016109ac90614ef2565b6118dc613dc6565b600054610100900460ff166118dc5760405162461bcd60e51b81526004016109ac90614ef2565b6000601436108015906137ff57503360009081526065602052604090205460ff165b15613811575060131936013560601c90565b503390565b600061386b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613dfd9092919063ffffffff16565b805190915015611cf157808060200190518101906138899190614bbd565b611cf15760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109ac565b6001600160a01b0381163b6139555760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016109ac565b600080516020614f7f83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61398d83613e0c565b60008251118061399a5750805b15611cf157612a458383613e4c565b600082815260fc602052604080822060fe5460068201546007830154935163353bb87f60e21b81526004810191909152602481019390935290929182916001600160a01b03169063d4eee1fc90604401600060405180830381865afa158015613a16573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613a3e91908101906147ab565b60a0820151608082015160088701549395509193509160009061271090613a6a90899061ffff16614e0f565b613a749190614e26565b600887015490915060009061271090613a98908a9062010000900461ffff16614e0f565b613aa29190614e26565b600888015490915060009061271090613ac8908b90640100000000900461ffff16614e0f565b613ad29190614e26565b60038901546001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc6020526040812080549293508592909190613b22908490614c37565b9091555050600085815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054849290613b5d908490614c37565b9091555050600084815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054839290613b98908490614c37565b90915550506003880154600689015460408051888152602081019290925281018490526001600160a01b03909116907f17c48ab8e1617182f35ae77fd7da7f4e15dedf7018aa371a4481c20c790b65469060600160405180910390a26003880154600689015460408051878152602081019290925281018490526001600160a01b03909116907f3476ed3eea2cdac584273bc8830824c8ca42ca2a99e9f144a87a1cdbbf9dd15a9060600160405180910390a250505050505050505050565b600083815260fc6020526040908190208054600382015460068301546007840154945193947ff3afebb51c3c2b45151cf0572b3d287505cf6ecea01df5f222c1d8cf0159f22794613cb8949389936001600160a01b03909116928992614f3d565b60405180910390a18060040154600003612a455760fe5460068201546005830154604051635ab9ae0f60e11b8152600481019290925260248201526001600160a01b039091169063b5735c1e90604401600060405180830381600087803b158015613d2257600080fd5b505af1158015613d36573d6000803e3d6000fd5b505050507f6bef1b5e95b741d6e665eb9b5c2d3e1203c46a771451055a9d41e0b8ff4510b78160060154604051613d6f91815260200190565b60405180910390a150505050565b60665460ff166118dc5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016109ac565b600054610100900460ff16613ded5760405162461bcd60e51b81526004016109ac90614ef2565b6118dc613df861292a565b6135b7565b60606129e18484600085613f42565b613e15816138e8565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b613eb45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016109ac565b600080846001600160a01b031684604051613ecf9190614a03565b600060405180830381855af49150503d8060008114613f0a576040519150601f19603f3d011682016040523d82523d6000602084013e613f0f565b606091505b5091509150613f378282604051806060016040528060278152602001614fbf6027913961401d565b925050505b92915050565b606082471015613fa35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016109ac565b600080866001600160a01b03168587604051613fbf9190614a03565b60006040518083038185875af1925050503d8060008114613ffc576040519150601f19603f3d011682016040523d82523d6000602084013e614001565b606091505b509150915061401287838387614036565b979650505050505050565b6060831561402c5750816129e4565b6129e483836140ab565b606083156140a557825160000361409e576001600160a01b0385163b61409e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109ac565b50816112fb565b6112fb83835b8151156140bb5781518083602001fd5b8060405162461bcd60e51b81526004016109ac9190614dfc565b6001600160a01b03811681146115b157600080fd5b6000602082840312156140fc57600080fd5b81356129e4816140d5565b60006020828403121561411957600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b6005811061414657614146614120565b9052565b60005b8381101561416557818101518382015260200161414d565b50506000910152565b6000815180845261418681602086016020860161414a565b601f01601f19169290920160200192915050565b6020815281516020820152600060208301516141c160408401826001600160a01b03169052565b5060408301516001600160a01b03811660608401525060608301516001600160a01b038116608084015250608083015160a083015260a083015160c083015260c083015160e083015260e08301516101008181850152808501519150506101206142308185018361ffff169052565b84015190506101406142478482018361ffff169052565b840151905061016061425e8482018361ffff169052565b840151905061018061427a848201836001600160a01b03169052565b84015190506101a061428e84820183614136565b8401516101c0848101919091528401516101e0808501919091528401516102008085019190915284015161022080850191909152840151610260610240808601829052919250906142e361028086018461416e565b9501519301929092525090919050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff8111828210171561432c5761432c6142f3565b60405290565b60405160c0810167ffffffffffffffff8111828210171561432c5761432c6142f3565b604051610160810167ffffffffffffffff8111828210171561432c5761432c6142f3565b604051601f8201601f1916810167ffffffffffffffff811182821017156143a2576143a26142f3565b604052919050565b600067ffffffffffffffff8211156143c4576143c46142f3565b50601f01601f191660200190565b60006143e56143e0846143aa565b614379565b90508281528383830111156143f957600080fd5b828260208301376000602084830101529392505050565b600082601f83011261442157600080fd5b6129e4838335602085016143d2565b6000806000806080858703121561444657600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561446c57600080fd5b61447888838901614410565b9350606087013591508082111561448e57600080fd5b5061449b87828801614410565b91505092959194509250565b600080604083850312156144ba57600080fd5b50508035926020909101359150565b6000806000606084860312156144de57600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561450857600080fd5b8235614513816140d5565b9150602083013567ffffffffffffffff81111561452f57600080fd5b8301601f8101851361454057600080fd5b61454f858235602084016143d2565b9150509250929050565b60008060006060848603121561456e57600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561459357600080fd5b61459f86828701614410565b9150509250925092565b600080604083850312156145bc57600080fd5b8235915060208301356145ce816140d5565b809150509250929050565b61ffff811681146115b157600080fd5b6000602082840312156145fb57600080fd5b81356129e4816145d9565b6000806000806080858703121561461c57600080fd5b8435614627816140d5565b93506020850135614637816140d5565b92506040850135614647816140d5565b91506060850135614657816140d5565b939692955090935050565b60006020828403121561467457600080fd5b5051919050565b600181811c9082168061468f57607f821691505b6020821081036146af57634e487b7160e01b600052602260045260246000fd5b50919050565b600082601f8301126146c657600080fd5b81516146d46143e0826143aa565b8181528460208386010111156146e957600080fd5b6112fb82602083016020870161414a565b80516002811061470957600080fd5b919050565b8051614709816140d5565b600060e0828403121561472b57600080fd5b614733614309565b905061473e826146fa565b8152602082015160208201526147566040830161470e565b6040820152606082015160608201526080820151608082015260a082015167ffffffffffffffff81111561478957600080fd5b614795848285016146b5565b60a08301525060c082015160c082015292915050565b600080604083850312156147be57600080fd5b825167ffffffffffffffff808211156147d657600080fd5b9084019060c082870312156147ea57600080fd5b6147f2614332565b82516005811061480157600080fd5b80825250602083015160208201526040830151604082015260608301518281111561482b57600080fd5b614837888286016146b5565b6060830152506080830151608082015260a083015160a082015280945050602085015191508082111561486957600080fd5b5061454f85828601614719565b6000806040838503121561488957600080fd5b8251614894816140d5565b60208401519092506145ce816140d5565b8051614709816145d9565b6000602082840312156148c257600080fd5b815167ffffffffffffffff808211156148da57600080fd5b9083019061016082860312156148ef57600080fd5b6148f7614355565b8251815260208301518281111561490d57600080fd5b614919878286016146b5565b60208301525060408301518281111561493157600080fd5b61493d878286016146b5565b60408301525061494f606084016148a5565b6060820152614960608084016148a5565b608082015260a083015160a082015260c083015160c082015261498560e0840161470e565b60e0820152610100808401518381111561499e57600080fd5b6149aa888287016146b5565b8284015250506101209150818301518282015261014091506149cd82840161470e565b91810191909152949350505050565b6020808252600d908201526c1058d8d95cdcc819195b9a5959609a1b604082015260600190565b60008251614a1581846020870161414a565b9190910192915050565b601f821115611cf157600081815260208120601f850160051c81016020861015614a465750805b601f850160051c820191505b8181101561370c57828155600101614a52565b815167ffffffffffffffff811115614a7f57614a7f6142f3565b614a9381614a8d845461467b565b84614a1f565b602080601f831160018114614ac85760008415614ab05750858301515b600019600386901b1c1916600185901b17855561370c565b600085815260208120601f198616915b82811015614af757888601518255948401946001909101908401614ad8565b5085821015614b155787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215614bcf57600080fd5b815180151581146129e457600080fd5b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b81810381811115613f3c57613f3c614c0e565b80820180821115613f3c57613f3c614c0e565b602080825260129082015271105c989a5d1c985d1bdc881b9bdd081cd95d60721b604082015260600190565b6020808252604d908201527f446973707574652068617320616c7265616479206265656e206372656174656460408201527f206f72206265636175736520746865207472616e73616374696f6e206861732060608201526c1899595b88195e1958dd5d1959609a1b608082015260a00190565b60008154614cf68161467b565b808552602060018381168015614d135760018114614d2d57614d5b565b60ff1985168884015283151560051b880183019550614d5b565b866000528260002060005b85811015614d535781548a8201860152908301908401614d38565b890184019650505b505050505092915050565b6020815260006129e46020830184614ce9565b600281106115b1576115b1614120565b60608101614d9685614d79565b848252614da284614d79565b602082019390935260400152919050565b60208101614dc083614d79565b91905290565b8281526040602082015260006129e16040830184614ce9565b600060208284031215614df157600080fd5b81516129e4816140d5565b6020815260006129e4602083018461416e565b8082028115828204841417613f3c57613f3c614c0e565b600082614e4357634e487b7160e01b600052601260045260246000fd5b500490565b8d8152602081018d9052604081018c90526001600160a01b038b81166060830152608082018b905260a082018a905260c0820189905261ffff88811660e08401528781166101008401528616610120830152841661014082015260006101a080610160840152614eba81840186614ce9565b915050826101808301529e9d5050505050505050505050505050565b60ff831681526040602082015260006129e16040830184614ce9565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b86815260c08101614f4d87614d79565b60208201969096526001600160a01b039490941660408501526060840192909252608083015260a09091015291905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc73e533bc8a993eccbc1023beebad0020f6b6c3639f83062f00fc194b4d1172ba416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a7f8bc736209ed86b0a75451b8ebeb8112ce6d951fbc6a029e99724cff4fa1e364736f6c63430008110033", + "deployedBytecode": "0x6080604052600436106101cd5760003560e01c80635a34257a116100f75780638b69fa0a11610095578063e308a09911610064578063e308a09914610523578063eb63612d14610543578063f2fde38b14610563578063f8c8765e1461058357600080fd5b80638b69fa0a146104a55780638da5cb5b146104c55780639dcc5daf146104e3578063ddd5e1b21461050357600080fd5b8063715018a6116100d1578063715018a6146104555780637b44cdb51461046a5780637e69b7b01461047d5780638456cb591461049057600080fd5b80635a34257a146103f45780635c975abb1461042a5780636e72b4521461044257600080fd5b80633659cfe61161016f5780633f4ba83a1161013e5780633f4ba83a1461036e5780634f1ef2861461038357806352d1902d14610396578063572b6c05146103ab57600080fd5b80633659cfe6146102ee5780633751d89c1461030e5780633a1121cd1461032e5780633ab4a6a41461034e57600080fd5b806315734fe7116101ab57806315734fe71461026b57806326d006681461027e5780632fbe3b03146102a0578063311a6c56146102ce57600080fd5b806306d6e63f146101d25780630a1a47d6146102105780630fa683d31461023e575b600080fd5b3480156101de57600080fd5b50610101546101f3906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021c57600080fd5b5061023061022b3660046140ea565b6105a3565b604051908152602001610207565b34801561024a57600080fd5b5061025e610259366004614107565b61070f565b604051610207919061419a565b610230610279366004614430565b610a5d565b34801561028a57600080fd5b5061029e6102993660046140ea565b611303565b005b3480156102ac57600080fd5b506102306102bb366004614107565b6101026020526000908152604090205481565b3480156102da57600080fd5b5061029e6102e93660046144a7565b611366565b3480156102fa57600080fd5b5061029e6103093660046140ea565b6114d5565b34801561031a57600080fd5b5061029e6103293660046140ea565b6115b4565b34801561033a57600080fd5b5061029e6103493660046144c9565b61160d565b34801561035a57600080fd5b5061029e610369366004614107565b611716565b34801561037a57600080fd5b5061029e6118cc565b61029e6103913660046144f5565b6118de565b3480156103a257600080fd5b506102306119aa565b3480156103b757600080fd5b506103e46103c63660046140ea565b6001600160a01b031660009081526065602052604090205460ff1690565b6040519015158152602001610207565b34801561040057600080fd5b506101015461041790600160a01b900461ffff1681565b60405161ffff9091168152602001610207565b34801561043657600080fd5b5060665460ff166103e4565b61029e610450366004614107565b611a5d565b34801561046157600080fd5b5061029e611cf6565b61029e610478366004614107565b611d08565b61029e61048b366004614107565b611f82565b34801561049c57600080fd5b5061029e61203a565b3480156104b157600080fd5b5061029e6104c0366004614559565b61204a565b3480156104d157600080fd5b506033546001600160a01b03166101f3565b3480156104ef57600080fd5b5061029e6104fe3660046144c9565b6123ad565b34801561050f57600080fd5b5061029e61051e3660046145a9565b61249b565b34801561052f57600080fd5b5061029e61053e3660046140ea565b6126af565b34801561054f57600080fd5b5061029e61055e3660046145e9565b6126da565b34801561056f57600080fd5b5061029e61057e3660046140ea565b612733565b34801561058f57600080fd5b5061029e61059e366004614606565b6127a9565b6000806105ae61292a565b9050806001600160a01b03166105cc6033546001600160a01b031690565b6001600160a01b0316036106165750506001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc602052604090205490565b61010054604051631847c06b60e01b81526001600160a01b0383811660048301526000921690631847c06b90602401602060405180830381865afa158015610662573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106869190614662565b6101005460405162f577a560e81b8152600481018390529192506001600160a01b03169063f577a5009060240160006040518083038186803b1580156106cb57600080fd5b505afa1580156106df573d6000803e3d6000fd5b50505060009182525060fd602090815260408083206001600160a01b039096168352949052929092205492915050565b6107a96040805161026081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290529061018082019081526020016000815260200160008152602001600081526020016000815260200160608152602001600081525090565b600082815260fc602090815260408083208151610260810183528154815260018201546001600160a01b039081169482019490945260028201548416928101929092526003810154831660608301526004808201546080840152600582015460a0840152600682015460c0840152600782015460e0840152600882015461ffff8082166101008601526201000082048116610120860152640100000000820416610140850152600160301b810490941661016084015291929091610180840191600160d01b900460ff169081111561088357610883614120565b600481111561089457610894614120565b815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d820180546108d09061467b565b80601f01602080910402602001604051908101604052809291908181526020018280546108fc9061467b565b80156109495780601f1061091e57610100808354040283529160200191610949565b820191906000526020600020905b81548152906001019060200180831161092c57829003601f168201915b50505050508152602001600e8201548152505090506109686101035490565b8151106109b55760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064015b60405180910390fd5b60006109bf61292a565b905081602001516001600160a01b0316816001600160a01b031614806109fa575081604001516001600160a01b0316816001600160a01b0316145b610a565760405162461bcd60e51b815260206004820152602760248201527f596f7520617265206e6f742072656c6174656420746f2074686973207472616e60448201526639b0b1ba34b7b760c91b60648201526084016109ac565b5092915050565b6000610a67612939565b60fe5460405163353bb87f60e21b8152600481018790526024810186905260009182916001600160a01b039091169063d4eee1fc90604401600060405180830381865afa158015610abc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ae491908101906147ab565b60ff54602083810151908301516040516303ef723760e61b81526004810192909252602482015292945090925060009182916001600160a01b03169063fbdc8dc0906044016040805180830381865afa158015610b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b699190614876565b6101005460a0870151604051630b7a459360e31b815260048101919091529294509092506000916001600160a01b0390911690635bd22c9890602401600060405180830381865afa158015610bc2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610bea91908101906148b0565b9050600084608001518660a0015103610c035781610c80565b610100546080860151604051630b7a459360e31b81526001600160a01b0390921691635bd22c9891610c3b9160040190815260200190565b600060405180830381865afa158015610c58573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c8091908101906148b0565b90506000610c9b86606001518460600151846080015161297f565b60408701519091506001600160a01b0316610cf957803414610cf45760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016109ac565b610d3c565b3415610d3c5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016109ac565b846001600160a01b0316610d4e61292a565b6001600160a01b031614610d745760405162461bcd60e51b81526004016109ac906149dc565b8a866020015114610dbf5760405162461bcd60e51b8152602060048201526015602482015274125b98dbdc9c9958dd081c1c9bdc1bdcd85b081251605a1b60448201526064016109ac565b428660c001511015610e065760405162461bcd60e51b815260206004820152601060248201526f141c9bdc1bdcd85b08195e1c1a5c995960821b60448201526064016109ac565b600087516004811115610e1b57610e1b614120565b14610e685760405162461bcd60e51b815260206004820152601760248201527f5365727669636520737461747573206e6f74206f70656e00000000000000000060448201526064016109ac565b600086516001811115610e7d57610e7d614120565b14610eca5760405162461bcd60e51b815260206004820152601b60248201527f50726f706f73616c20737461747573206e6f742070656e64696e67000000000060448201526064016109ac565b8951602e14610f095760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b60448201526064016109ac565b88604051602001610f1a9190614a03565b604051602081830303815290604052805190602001208660a00151604051602001610f459190614a03565b6040516020818303038152906040528051906020012014610fa85760405162461bcd60e51b815260206004820152601c60248201527f50726f706f73616c206461746155726920686173206368616e6765640000000060448201526064016109ac565b6000610fb46101035490565b9050604051806102600160405280828152602001876001600160a01b03168152602001866001600160a01b0316815260200188604001516001600160a01b0316815260200188606001518152602001600081526020018e81526020018d815260200161010160149054906101000a900461ffff1661ffff168152602001856060015161ffff168152602001846080015161ffff1681526020018560e001516001600160a01b031681526020016000600481111561107357611073614120565b8152600060208083018290526040808401839052606080850184905242608080870191909152610100808c015160a080890191909152610120808e015160c0998a01528a885260fc87529685902089518155958901516001870180546001600160a01b039283166001600160a01b031991821617909155958a01516002880180549183169188169190911790559389015160038701805491861691909616179094559087015160048086019190915592870151600585015594860151600684015560e086015160078401559385015160088301805494870151610140880151610160890151909716600160301b026601000000000000600160d01b031961ffff9889166401000000000216640100000000600160d01b0319928916620100000263ffffffff19909816989094169790971795909517949094161793909317808355610180850151919391929160ff60d01b1990911690600160d01b9084908111156111e0576111e0614120565b02179055506101a082015160098201556101c0820151600a8201556101e0820151600b820155610200820151600c820155610220820151600d8201906112269082614a65565b5061024082015181600e015590505061124461010380546001019055565b60fe546040516353eaf57560e11b8152600481018f9052602481018e9052604481018390526001600160a01b039091169063a7d5eaea90606401600060405180830381600087803b15801561129857600080fd5b505af11580156112ac573d6000803e3d6000fd5b5050505060408701516001600160a01b0316156112dd5760408701516112dd906001600160a01b03168730856129eb565b6112f188602001518860200151838e612a4b565b9750505050505050505b949350505050565b61130b612b66565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b600061137061292a565b6000848152610102602090815260408083205480845260fc909252909120600881015492935090916001600160a01b03808516600160301b90920416146114035760405162461bcd60e51b815260206004820152602160248201527f5468652063616c6c6572206d757374206265207468652061726269747261746f6044820152603960f91b60648201526084016109ac565b60036008820154600160d01b900460ff16600481111561142557611425614120565b146114805760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652068617320616c7265616479206265656e207265736044820152641bdb1d995960da1b60648201526084016109ac565b84836001600160a01b03167f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e75622276866040516114bc91815260200190565b60405180910390a36114ce8285612bdf565b5050505050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361151d5760405162461bcd60e51b81526004016109ac90614b25565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611566600080516020614f7f833981519152546001600160a01b031690565b6001600160a01b03161461158c5760405162461bcd60e51b81526004016109ac90614b71565b61159581612e69565b604080516000808252602082019092526115b191839190612e71565b50565b6115bc612b66565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee6910161135b565b611615612939565b60ff5483906001600160a01b0316632fa117e58261163161292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561167b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169f9190614bbd565b6116bb5760405162461bcd60e51b81526004016109ac90614bdf565b6116c88360008685612fdc565b600083815260fc60205260408120600481018054919285926116eb908490614c24565b92505081905550828160050160008282546117069190614c37565b909155506114ce905084846132c7565b600081815260fc60205260409020600e810154600c8201546117389042614c24565b10156117865760405162461bcd60e51b815260206004820152601f60248201527f54696d656f75742074696d6520686173206e6f7420706173736564207965740060448201526064016109ac565b60016008820154600160d01b900460ff1660048111156117a8576117a8614120565b0361182b57600a8101541561181c57600a81018054600091829055600183015460405191926001600160a01b0390911691839181818185875af1925050503d8060008114611812576040519150601f19603f3d011682016040523d82523d6000602084013e611817565b606091505b505050505b611827826002612bdf565b5050565b60026008820154600160d01b900460ff16600481111561184d5761184d614120565b0361182757600b810154156118c157600b81018054600091829055600283015460405191926001600160a01b0390911691839181818185875af1925050503d80600081146118b7576040519150601f19603f3d011682016040523d82523d6000602084013e6118bc565b606091505b505050505b611827826001612bdf565b6118d4612b66565b6118dc61330c565b565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036119265760405162461bcd60e51b81526004016109ac90614b25565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661196f600080516020614f7f833981519152546001600160a01b031690565b6001600160a01b0316146119955760405162461bcd60e51b81526004016109ac90614b71565b61199e82612e69565b61182782826001612e71565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a4a5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016109ac565b50600080516020614f7f83398151915290565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611a9c5760405162461bcd60e51b81526004016109ac90614c4a565b60036008820154600160d01b900460ff166004811115611abe57611abe614120565b10611adb5760405162461bcd60e51b81526004016109ac90614c76565b60028101546001600160a01b0316611af161292a565b6001600160a01b031614611b475760405162461bcd60e51b815260206004820152601f60248201527f5468652063616c6c6572206d757374206265207468652072656365697665720060448201526064016109ac565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611b8490600d860190600401614d66565b602060405180830381865afa158015611ba1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc59190614662565b90503482600b016000828254611bdb9190614c37565b9091555050600b8201548114611c525760405162461bcd60e51b815260206004820152603660248201527f54686520726563656976657220666565206d75737420626520657175616c20746044820152751bc81d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60521b60648201526084016109ac565b42600c8301556040518390600080516020614f9f83398151915290611c7e906000906001903490614d89565b60405180910390a28082600a01541015611ce75760088201805460ff60d01b1916600160d01b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611cda90600090614db3565b60405180910390a2505050565b611cf18382613364565b505050565b611cfe612b66565b6118dc60006135b7565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611d475760405162461bcd60e51b81526004016109ac90614c4a565b60036008820154600160d01b900460ff166004811115611d6957611d69614120565b10611d865760405162461bcd60e51b81526004016109ac90614c76565b60018101546001600160a01b0316611d9c61292a565b6001600160a01b031614611df25760405162461bcd60e51b815260206004820152601d60248201527f5468652063616c6c6572206d757374206265207468652073656e64657200000060448201526064016109ac565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611e2f90600d860190600401614d66565b602060405180830381865afa158015611e4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e709190614662565b90503482600a016000828254611e869190614c37565b9091555050600a8201548114611efb5760405162461bcd60e51b815260206004820152603460248201527f5468652073656e64657220666565206d75737420626520657175616c20746f206044820152731d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60621b60648201526084016109ac565b42600c8301556040518390600080516020614f9f83398151915290611f269060009081903490614d89565b60405180910390a28082600b01541015611ce75760088201805460ff60d01b1916600160d11b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611cda90600190614db3565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611fc15760405162461bcd60e51b81526004016109ac90614c4a565b6008810154600982015460405163093225f160e31b8152600160301b9092046001600160a01b0316916349912f889134916120049190600d870190600401614dc6565b6000604051808303818588803b15801561201d57600080fd5b505af1158015612031573d6000803e3d6000fd5b50505050505050565b612042612b66565b6118dc613609565b60ff5483906001600160a01b0316632fa117e58261206661292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156120b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d49190614bbd565b6120f05760405162461bcd60e51b81526004016109ac90614bdf565b8151602e1461212f5760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b60448201526064016109ac565b600083815260fc602052604090206008810154600160301b90046001600160a01b031661216e5760405162461bcd60e51b81526004016109ac90614c4a565b60ff546040516331a9108f60e11b8152600481018790526000916001600160a01b031690636352211e90602401602060405180830381865afa1580156121b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121dc9190614ddf565b60018301549091506001600160a01b038083169116148061220c575060028201546001600160a01b038281169116145b612280576040805162461bcd60e51b81526020600482015260248101919091527f5468652063616c6c6572206d757374206265207468652073656e646572206f7260448201527f20746865207265636569766572206f722074686569722064656c65676174657360648201526084016109ac565b60046008830154600160d01b900460ff1660048111156122a2576122a2614120565b106123095760405162461bcd60e51b815260206004820152603160248201527f4d757374206e6f742073656e642065766964656e6365206966207468652064696044820152701cdc1d5d19481a5cc81c995cdbdb1d9959607a1b60648201526084016109ac565b806001600160a01b0316858360080160069054906101000a90046001600160a01b03166001600160a01b03167fdccf2f8b2cc26eafcd61905cba744cff4b81d14740725f6376390dc6298a6a3c876040516123649190614dfc565b60405180910390a485857fd998ce0f89c38b0f93256f0b843a404a3a3c5055b75265623f7cb9c369a1dd628660405161239d9190614dfc565b60405180910390a3505050505050565b6123b5612939565b60ff5483906001600160a01b0316632fa117e5826123d161292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561241b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243f9190614bbd565b61245b5760405162461bcd60e51b81526004016109ac90614bdf565b6124688360018685612fdc565b600083815260fc602052604081206004810180549192859261248b908490614c24565b909155506114ce90508484613647565b6124a3612939565b60006124ad61292a565b6001600160a01b03166124c86033546001600160a01b031690565b6001600160a01b0316036125075782156124f45760405162461bcd60e51b81526004016109ac906149dc565b50610101546001600160a01b03166125d4565b6101005460405162f577a560e81b8152600481018590526001600160a01b039091169063f577a5009060240160006040518083038186803b15801561254b57600080fd5b505afa15801561255f573d6000803e3d6000fd5b5050610100546040516331a9108f60e11b8152600481018790526001600160a01b039091169250636352211e9150602401602060405180830381865afa1580156125ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d19190614ddf565b90505b600083815260fd602090815260408083206001600160a01b0386168452909152902054806126375760405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b60448201526064016109ac565b600084815260fd602090815260408083206001600160a01b03871684529091528120556126658284836136ad565b60408051858152602081018390526001600160a01b038516917f2227733fc4c8a9034cb58087dcf6995128b9c0233b038b03366aaf30c92b92d6910160405180910390a250505050565b6126b7612b66565b61010180546001600160a01b0319166001600160a01b0392909216919091179055565b6126e2612b66565b610101805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f8339189e972f7fba792126e752aa8485af08710bce4a041c5bc3f9858acd71309060200161135b565b61273b612b66565b6001600160a01b0381166127a05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109ac565b6115b1816135b7565b600054610100900460ff16158080156127c95750600054600160ff909116105b806127e35750303b1580156127e3575060005460ff166001145b6128465760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016109ac565b6000805460ff191660011790558015612869576000805461ff0019166101001790555b612871613787565b6128796137b6565b60fe80546001600160a01b038088166001600160a01b03199283161790925560ff805487841690831617905561010080548684169083161790556101018054928516929091169190911790556128d461010380546001019055565b6128de60646126da565b80156114ce576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b60006129346137dd565b905090565b60665460ff16156118dc5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016109ac565b600061271061299261ffff841686614e0f565b6129a061ffff861687614e0f565b610101546129b990600160a01b900461ffff1688614e0f565b6129c39190614c37565b6129cd9190614c37565b6129d79190614e26565b6129e19085614c37565b90505b9392505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612a45908590613816565b50505050565b600060fc600084815260200190815260200160002090507f8b4f0e94aa0aee74c276abd2d92a5e2737a493b055e19d5b2d4c0ac573242a158386868460030160009054906101000a90046001600160a01b031685600401548660060154876007015461010160149054906101000a900461ffff168960080160029054906101000a900461ffff168a60080160049054906101000a900461ffff168b60080160069054906101000a90046001600160a01b03168c600d018d600e0154604051612b1f9d9c9b9a99989796959493929190614e48565b60405180910390a1827f61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d83604051612b579190614dfc565b60405180910390a25050505050565b612b6e61292a565b6001600160a01b0316612b896033546001600160a01b031690565b6001600160a01b0316146118dc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ac565b600082815260fc602052604090206002821115612c2f5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c69642072756c696e6760901b60448201526064016109ac565b60018101546002820154600483018054600a85018054600b87018054600095869055928590559390935560088601805460ff60d01b1916600160d21b1790556001600160a01b0394851694909316929091906000198701612cea576040516001600160a01b038616908390600081818185875af1925050503d8060008114612cd3576040519150601f19603f3d011682016040523d82523d6000602084013e612cd8565b606091505b505050612ce58884613647565b612e25565b6001198701612d4e576040516001600160a01b038516908290600081818185875af1925050503d8060008114612d3c576040519150601f19603f3d011682016040523d82523d6000602084013e612d41565b606091505b505050612ce588846132c7565b6000612d5b600284614e26565b90506000612d6a600286614e26565b9050612d768a82613647565b612d808a826132c7565b6040516001600160a01b038816908390600081818185875af1925050503d8060008114612dc9576040519150601f19603f3d011682016040523d82523d6000602084013e612dce565b606091505b50506040516001600160a01b03881691508390600081818185875af1925050503d8060008114612e1a576040519150601f19603f3d011682016040523d82523d6000602084013e612e1f565b606091505b50505050505b877f76b363d70472d47d20e4119f3625c05ed37ca51b1d9e1cd8b87d8c20530640f388604051612e5791815260200190565b60405180910390a25050505050505050565b6115b1612b66565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612ea457611cf1836138e8565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612efe575060408051601f3d908101601f19168201909252612efb91810190614662565b60015b612f615760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016109ac565b600080516020614f7f8339815191528114612fd05760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016109ac565b50611cf1838383613984565b600084815260fc6020526040812090846001811115612ffd57612ffd614120565b036130a35760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa15801561304b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306f9190614ddf565b60018201546001600160a01b0390811691161461309e5760405162461bcd60e51b81526004016109ac906149dc565b613158565b60018460018111156130b7576130b7614120565b036131585760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa158015613105573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131299190614ddf565b60028201546001600160a01b039081169116146131585760405162461bcd60e51b81526004016109ac906149dc565b610103548154106131a45760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064016109ac565b60006008820154600160d01b900460ff1660048111156131c6576131c6614120565b146132215760405162461bcd60e51b815260206004820152602560248201527f546865207472616e73616374696f6e2073686f756c646e2774206265206469736044820152641c1d5d195960da1b60648201526084016109ac565b818160040154101561326a5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b60448201526064016109ac565b6127108210158061328a57506127108210801561328a5750806004015482145b6114ce5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016109ac565b6132d182826139a9565b600082815260fc6020526040902060028101546003820154613300916001600160a01b039081169116846136ad565b611cf183600084613c57565b613314613d7d565b6066805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61334761292a565b6040516001600160a01b03909116815260200160405180910390a1565b600082815260fc60205260409081902060088101805460ff60d01b1916600360d01b1790819055915163c13517e160e01b81529091600160301b90046001600160a01b031690819063c13517e19085906133c890600290600d880190600401614ed6565b60206040518083038185885af11580156133e6573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061340b9190614662565b600983018181556000918252610102602090815260409283902087905590548251878152918201879052916001600160a01b038416917f74baab670a4015ab2f1b467c5252a96141a2573f2908e58a92081e80d3cfde3d910160405180910390a38282600a015411156135175760008383600a015461348a9190614c24565b600a840185905560018401546040519192506001600160a01b0316908290600081818185875af1925050503d80600081146134e1576040519150601f19603f3d011682016040523d82523d6000602084013e6134e6565b606091505b50505084600080516020614f9f833981519152600160003460405161350d93929190614d89565b60405180910390a2505b8282600b01541115612a455760008383600b01546135359190614c24565b600b840185905560028401546040519192506001600160a01b0316908290600081818185875af1925050503d806000811461358c576040519150601f19603f3d011682016040523d82523d6000602084013e613591565b606091505b50505084600080516020614f9f83398151915260018034604051612b5793929190614d89565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b613611612939565b6066805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861334761292a565b600082815260fc60205260408120600881015490919061367d90849061ffff62010000820481169164010000000090041661297f565b600183015460038401549192506136a1916001600160a01b039182169116836136ad565b612a4584600185613c57565b6001600160a01b038216600003613714576040516001600160a01b038416908290600081818185875af1925050503d8060008114613707576040519150601f19603f3d011682016040523d82523d6000602084013e61370c565b606091505b505050505050565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb906044016020604051808303816000875af1158015613763573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a459190614bbd565b600054610100900460ff166137ae5760405162461bcd60e51b81526004016109ac90614ef2565b6118dc613dc6565b600054610100900460ff166118dc5760405162461bcd60e51b81526004016109ac90614ef2565b6000601436108015906137ff57503360009081526065602052604090205460ff165b15613811575060131936013560601c90565b503390565b600061386b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613dfd9092919063ffffffff16565b805190915015611cf157808060200190518101906138899190614bbd565b611cf15760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109ac565b6001600160a01b0381163b6139555760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016109ac565b600080516020614f7f83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61398d83613e0c565b60008251118061399a5750805b15611cf157612a458383613e4c565b600082815260fc602052604080822060fe5460068201546007830154935163353bb87f60e21b81526004810191909152602481019390935290929182916001600160a01b03169063d4eee1fc90604401600060405180830381865afa158015613a16573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613a3e91908101906147ab565b60a0820151608082015160088701549395509193509160009061271090613a6a90899061ffff16614e0f565b613a749190614e26565b600887015490915060009061271090613a98908a9062010000900461ffff16614e0f565b613aa29190614e26565b600888015490915060009061271090613ac8908b90640100000000900461ffff16614e0f565b613ad29190614e26565b60038901546001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc6020526040812080549293508592909190613b22908490614c37565b9091555050600085815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054849290613b5d908490614c37565b9091555050600084815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054839290613b98908490614c37565b90915550506003880154600689015460408051888152602081019290925281018490526001600160a01b03909116907f17c48ab8e1617182f35ae77fd7da7f4e15dedf7018aa371a4481c20c790b65469060600160405180910390a26003880154600689015460408051878152602081019290925281018490526001600160a01b03909116907f3476ed3eea2cdac584273bc8830824c8ca42ca2a99e9f144a87a1cdbbf9dd15a9060600160405180910390a250505050505050505050565b600083815260fc6020526040908190208054600382015460068301546007840154945193947ff3afebb51c3c2b45151cf0572b3d287505cf6ecea01df5f222c1d8cf0159f22794613cb8949389936001600160a01b03909116928992614f3d565b60405180910390a18060040154600003612a455760fe5460068201546005830154604051635ab9ae0f60e11b8152600481019290925260248201526001600160a01b039091169063b5735c1e90604401600060405180830381600087803b158015613d2257600080fd5b505af1158015613d36573d6000803e3d6000fd5b505050507f6bef1b5e95b741d6e665eb9b5c2d3e1203c46a771451055a9d41e0b8ff4510b78160060154604051613d6f91815260200190565b60405180910390a150505050565b60665460ff166118dc5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016109ac565b600054610100900460ff16613ded5760405162461bcd60e51b81526004016109ac90614ef2565b6118dc613df861292a565b6135b7565b60606129e18484600085613f42565b613e15816138e8565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b613eb45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016109ac565b600080846001600160a01b031684604051613ecf9190614a03565b600060405180830381855af49150503d8060008114613f0a576040519150601f19603f3d011682016040523d82523d6000602084013e613f0f565b606091505b5091509150613f378282604051806060016040528060278152602001614fbf6027913961401d565b925050505b92915050565b606082471015613fa35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016109ac565b600080866001600160a01b03168587604051613fbf9190614a03565b60006040518083038185875af1925050503d8060008114613ffc576040519150601f19603f3d011682016040523d82523d6000602084013e614001565b606091505b509150915061401287838387614036565b979650505050505050565b6060831561402c5750816129e4565b6129e483836140ab565b606083156140a557825160000361409e576001600160a01b0385163b61409e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109ac565b50816112fb565b6112fb83835b8151156140bb5781518083602001fd5b8060405162461bcd60e51b81526004016109ac9190614dfc565b6001600160a01b03811681146115b157600080fd5b6000602082840312156140fc57600080fd5b81356129e4816140d5565b60006020828403121561411957600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b6005811061414657614146614120565b9052565b60005b8381101561416557818101518382015260200161414d565b50506000910152565b6000815180845261418681602086016020860161414a565b601f01601f19169290920160200192915050565b6020815281516020820152600060208301516141c160408401826001600160a01b03169052565b5060408301516001600160a01b03811660608401525060608301516001600160a01b038116608084015250608083015160a083015260a083015160c083015260c083015160e083015260e08301516101008181850152808501519150506101206142308185018361ffff169052565b84015190506101406142478482018361ffff169052565b840151905061016061425e8482018361ffff169052565b840151905061018061427a848201836001600160a01b03169052565b84015190506101a061428e84820183614136565b8401516101c0848101919091528401516101e0808501919091528401516102008085019190915284015161022080850191909152840151610260610240808601829052919250906142e361028086018461416e565b9501519301929092525090919050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff8111828210171561432c5761432c6142f3565b60405290565b60405160c0810167ffffffffffffffff8111828210171561432c5761432c6142f3565b604051610160810167ffffffffffffffff8111828210171561432c5761432c6142f3565b604051601f8201601f1916810167ffffffffffffffff811182821017156143a2576143a26142f3565b604052919050565b600067ffffffffffffffff8211156143c4576143c46142f3565b50601f01601f191660200190565b60006143e56143e0846143aa565b614379565b90508281528383830111156143f957600080fd5b828260208301376000602084830101529392505050565b600082601f83011261442157600080fd5b6129e4838335602085016143d2565b6000806000806080858703121561444657600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561446c57600080fd5b61447888838901614410565b9350606087013591508082111561448e57600080fd5b5061449b87828801614410565b91505092959194509250565b600080604083850312156144ba57600080fd5b50508035926020909101359150565b6000806000606084860312156144de57600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561450857600080fd5b8235614513816140d5565b9150602083013567ffffffffffffffff81111561452f57600080fd5b8301601f8101851361454057600080fd5b61454f858235602084016143d2565b9150509250929050565b60008060006060848603121561456e57600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561459357600080fd5b61459f86828701614410565b9150509250925092565b600080604083850312156145bc57600080fd5b8235915060208301356145ce816140d5565b809150509250929050565b61ffff811681146115b157600080fd5b6000602082840312156145fb57600080fd5b81356129e4816145d9565b6000806000806080858703121561461c57600080fd5b8435614627816140d5565b93506020850135614637816140d5565b92506040850135614647816140d5565b91506060850135614657816140d5565b939692955090935050565b60006020828403121561467457600080fd5b5051919050565b600181811c9082168061468f57607f821691505b6020821081036146af57634e487b7160e01b600052602260045260246000fd5b50919050565b600082601f8301126146c657600080fd5b81516146d46143e0826143aa565b8181528460208386010111156146e957600080fd5b6112fb82602083016020870161414a565b80516002811061470957600080fd5b919050565b8051614709816140d5565b600060e0828403121561472b57600080fd5b614733614309565b905061473e826146fa565b8152602082015160208201526147566040830161470e565b6040820152606082015160608201526080820151608082015260a082015167ffffffffffffffff81111561478957600080fd5b614795848285016146b5565b60a08301525060c082015160c082015292915050565b600080604083850312156147be57600080fd5b825167ffffffffffffffff808211156147d657600080fd5b9084019060c082870312156147ea57600080fd5b6147f2614332565b82516005811061480157600080fd5b80825250602083015160208201526040830151604082015260608301518281111561482b57600080fd5b614837888286016146b5565b6060830152506080830151608082015260a083015160a082015280945050602085015191508082111561486957600080fd5b5061454f85828601614719565b6000806040838503121561488957600080fd5b8251614894816140d5565b60208401519092506145ce816140d5565b8051614709816145d9565b6000602082840312156148c257600080fd5b815167ffffffffffffffff808211156148da57600080fd5b9083019061016082860312156148ef57600080fd5b6148f7614355565b8251815260208301518281111561490d57600080fd5b614919878286016146b5565b60208301525060408301518281111561493157600080fd5b61493d878286016146b5565b60408301525061494f606084016148a5565b6060820152614960608084016148a5565b608082015260a083015160a082015260c083015160c082015261498560e0840161470e565b60e0820152610100808401518381111561499e57600080fd5b6149aa888287016146b5565b8284015250506101209150818301518282015261014091506149cd82840161470e565b91810191909152949350505050565b6020808252600d908201526c1058d8d95cdcc819195b9a5959609a1b604082015260600190565b60008251614a1581846020870161414a565b9190910192915050565b601f821115611cf157600081815260208120601f850160051c81016020861015614a465750805b601f850160051c820191505b8181101561370c57828155600101614a52565b815167ffffffffffffffff811115614a7f57614a7f6142f3565b614a9381614a8d845461467b565b84614a1f565b602080601f831160018114614ac85760008415614ab05750858301515b600019600386901b1c1916600185901b17855561370c565b600085815260208120601f198616915b82811015614af757888601518255948401946001909101908401614ad8565b5085821015614b155787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215614bcf57600080fd5b815180151581146129e457600080fd5b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b81810381811115613f3c57613f3c614c0e565b80820180821115613f3c57613f3c614c0e565b602080825260129082015271105c989a5d1c985d1bdc881b9bdd081cd95d60721b604082015260600190565b6020808252604d908201527f446973707574652068617320616c7265616479206265656e206372656174656460408201527f206f72206265636175736520746865207472616e73616374696f6e206861732060608201526c1899595b88195e1958dd5d1959609a1b608082015260a00190565b60008154614cf68161467b565b808552602060018381168015614d135760018114614d2d57614d5b565b60ff1985168884015283151560051b880183019550614d5b565b866000528260002060005b85811015614d535781548a8201860152908301908401614d38565b890184019650505b505050505092915050565b6020815260006129e46020830184614ce9565b600281106115b1576115b1614120565b60608101614d9685614d79565b848252614da284614d79565b602082019390935260400152919050565b60208101614dc083614d79565b91905290565b8281526040602082015260006129e16040830184614ce9565b600060208284031215614df157600080fd5b81516129e4816140d5565b6020815260006129e4602083018461416e565b8082028115828204841417613f3c57613f3c614c0e565b600082614e4357634e487b7160e01b600052601260045260246000fd5b500490565b8d8152602081018d9052604081018c90526001600160a01b038b81166060830152608082018b905260a082018a905260c0820189905261ffff88811660e08401528781166101008401528616610120830152841661014082015260006101a080610160840152614eba81840186614ce9565b915050826101808301529e9d5050505050505050505050505050565b60ff831681526040602082015260006129e16040830184614ce9565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b86815260c08101614f4d87614d79565b60208201969096526001600160a01b039490941660408501526060840192909252608083015260a09091015291905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc73e533bc8a993eccbc1023beebad0020f6b6c3639f83062f00fc194b4d1172ba416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a7f8bc736209ed86b0a75451b8ebeb8112ce6d951fbc6a029e99724cff4fa1e364736f6c63430008110033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/packages/client/src/contracts/ABI/TalentLayerService.json b/packages/client/src/contracts/ABI/TalentLayerService.json index f5046a0..bef5883 100644 --- a/packages/client/src/contracts/ABI/TalentLayerService.json +++ b/packages/client/src/contracts/ABI/TalentLayerService.json @@ -8,6 +8,154 @@ "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ownerId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "platformId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "dataUri", + "type": "string" + } + ], + "name": "ServiceCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "dataUri", + "type": "string" + } + ], + "name": "ServiceDetailedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ownerId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "dataUri", + "type": "string" + }, + { + "indexed": false, + "internalType": "enum TalentLayerService.ProposalStatus", + "name": "status", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "address", + "name": "rateToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rateAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "platformId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "expirationDate", + "type": "uint256" + } + ], + "name": "ProposalCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "serviceId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ownerId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "dataUri", + "type": "string" + }, + { + "indexed": false, + "internalType": "address", + "name": "rateToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rateAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "expirationDate", + "type": "uint256" + } + ], + "name": "ProposalUpdated", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -139,26 +287,26 @@ }, { "indexed": false, - "internalType": "address", - "name": "rateToken", - "type": "address" + "internalType": "uint256", + "name": "amount", + "type": "uint256" }, { "indexed": false, "internalType": "uint256", - "name": "rateAmount", + "name": "platformId", "type": "uint256" }, { "indexed": false, "internalType": "uint256", - "name": "platformId", + "name": "expirationDate", "type": "uint256" }, { "indexed": false, "internalType": "uint256", - "name": "expirationDate", + "name": "referrerId", "type": "uint256" } ], @@ -188,20 +336,20 @@ }, { "indexed": false, - "internalType": "address", - "name": "rateToken", - "type": "address" + "internalType": "uint256", + "name": "amount", + "type": "uint256" }, { "indexed": false, "internalType": "uint256", - "name": "rateAmount", + "name": "expirationDate", "type": "uint256" }, { "indexed": false, "internalType": "uint256", - "name": "expirationDate", + "name": "referrerId", "type": "uint256" } ], @@ -322,6 +470,18 @@ "internalType": "string", "name": "dataUri", "type": "string" + }, + { + "indexed": false, + "internalType": "address", + "name": "rateToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "referralAmount", + "type": "uint256" } ], "name": "ServiceCreated", @@ -331,7 +491,7 @@ "anonymous": false, "inputs": [ { - "indexed": true, + "indexed": false, "internalType": "uint256", "name": "id", "type": "uint256" @@ -341,9 +501,15 @@ "internalType": "string", "name": "dataUri", "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "referralAmount", + "type": "uint256" } ], - "name": "ServiceDetailedUpdated", + "name": "ServiceUpdated", "type": "event" }, { @@ -519,11 +685,6 @@ "name": "_serviceId", "type": "uint256" }, - { - "internalType": "address", - "name": "_rateToken", - "type": "address" - }, { "internalType": "uint256", "name": "_rateAmount", @@ -548,6 +709,11 @@ "internalType": "bytes", "name": "_signature", "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_referrerId", + "type": "uint256" } ], "name": "createProposal", @@ -576,6 +742,16 @@ "internalType": "bytes", "name": "_signature", "type": "bytes" + }, + { + "internalType": "address", + "name": "_rateToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_referralAmount", + "type": "uint256" } ], "name": "createService", @@ -640,6 +816,11 @@ "internalType": "uint256", "name": "expirationDate", "type": "uint256" + }, + { + "internalType": "uint256", + "name": "referrerId", + "type": "uint256" } ], "internalType": "struct TalentLayerService.Proposal", @@ -710,6 +891,16 @@ "internalType": "uint256", "name": "platformId", "type": "uint256" + }, + { + "internalType": "address", + "name": "rateToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "referralAmount", + "type": "uint256" } ], "internalType": "struct TalentLayerService.Service", @@ -766,6 +957,16 @@ "internalType": "uint256", "name": "platformId", "type": "uint256" + }, + { + "internalType": "address", + "name": "rateToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "referralAmount", + "type": "uint256" } ], "internalType": "struct TalentLayerService.Service", @@ -808,6 +1009,11 @@ "internalType": "uint256", "name": "expirationDate", "type": "uint256" + }, + { + "internalType": "uint256", + "name": "referrerId", + "type": "uint256" } ], "internalType": "struct TalentLayerService.Proposal", @@ -1023,6 +1229,11 @@ "internalType": "uint256", "name": "expirationDate", "type": "uint256" + }, + { + "internalType": "uint256", + "name": "referrerId", + "type": "uint256" } ], "stateMutability": "view", @@ -1155,6 +1366,16 @@ "internalType": "uint256", "name": "platformId", "type": "uint256" + }, + { + "internalType": "address", + "name": "rateToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "referralAmount", + "type": "uint256" } ], "stateMutability": "view", @@ -1253,11 +1474,6 @@ "name": "_serviceId", "type": "uint256" }, - { - "internalType": "address", - "name": "_rateToken", - "type": "address" - }, { "internalType": "uint256", "name": "_rateAmount", @@ -1272,6 +1488,11 @@ "internalType": "uint256", "name": "_expirationDate", "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_referrerId", + "type": "uint256" } ], "name": "updateProposal", @@ -1291,13 +1512,18 @@ "name": "_serviceId", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_referralAmount", + "type": "uint256" + }, { "internalType": "string", "name": "_dataUri", "type": "string" } ], - "name": "updateServiceData", + "name": "updateService", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1334,8 +1560,8 @@ "type": "function" } ], - "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6080516142306200012060003960008181610f7c01528181610fbc01528181611273015281816112b3015261134201526142306000f3fe6080604052600436106102305760003560e01c8063715018a61161012e578063c2cfee27116100ab578063d547741f1161006f578063d547741f1461072b578063ef0e239b1461074b578063f2fde38b14610778578063f6c53d9b14610798578063f9eaee0d146107af57600080fd5b8063c2cfee2714610669578063c75858d51461069c578063ccaa7d2a146106bc578063d338ec9a146106ea578063d4eee1fc146106fd57600080fd5b8063a217fddf116100f2578063a217fddf146105b5578063a7d5eaea146105ca578063aba21009146105ea578063b5735c1e14610617578063c22c4f431461063757600080fd5b8063715018a6146104f057806371da85f9146105055780637c5a72cd146105575780638da5cb5b1461057757806391d148541461059557600080fd5b80632f2ff15d116101bc578063485cc95511610180578063485cc9551461043b5780634f1ef2861461045b57806352d1902d1461046e578063572b6c05146104835780636ce76f30146104bc57600080fd5b80632f2ff15d1461039b57806336568abe146103bb5780633659cfe6146103db5780633751d89c146103fb5780633ca2ad6f1461041b57600080fd5b80631499f9e6116102035780631499f9e6146102bf578063156b39aa146102f85780631db087ff1461031d578063248a9ca31461034b57806326d006681461037b57600080fd5b806301ffc9a714610235578063089b7c731461026a5780630e0660251461028c57806313ca98db146102ac575b600080fd5b34801561024157600080fd5b50610255610250366004613478565b6107e9565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061028a6102853660046134a2565b610820565b005b34801561029857600080fd5b5061028a6102a7366004613506565b6109c3565b61028a6102ba36600461356e565b610b8b565b3480156102cb57600080fd5b50610130546102e0906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b34801561030457600080fd5b5061030f6101365481565b604051908152602001610261565b34801561032957600080fd5b5061030f610338366004613624565b6101336020526000908152604090205481565b34801561035757600080fd5b5061030f610366366004613624565b600090815260fc602052604090206001015490565b34801561038757600080fd5b5061028a61039636600461363d565b610e57565b3480156103a757600080fd5b5061028a6103b636600461365a565b610eba565b3480156103c757600080fd5b5061028a6103d636600461365a565b610ee4565b3480156103e757600080fd5b5061028a6103f636600461363d565b610f72565b34801561040757600080fd5b5061028a61041636600461363d565b611051565b34801561042757600080fd5b5061028a610436366004613624565b6110aa565b34801561044757600080fd5b5061028a61045636600461368a565b6110f2565b61028a6104693660046136ce565b611269565b34801561047a57600080fd5b5061030f611335565b34801561048f57600080fd5b5061025561049e36600461363d565b6001600160a01b031660009081526065602052604090205460ff1690565b3480156104c857600080fd5b5061030f7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f81565b3480156104fc57600080fd5b5061028a6113e8565b34801561051157600080fd5b5061054061052036600461363d565b610135602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610261565b34801561056357600080fd5b5061028a6105723660046137a0565b6113fc565b34801561058357600080fd5b506033546001600160a01b03166102e0565b3480156105a157600080fd5b506102556105b036600461365a565b6114d1565b3480156105c157600080fd5b5061030f600081565b3480156105d657600080fd5b5061028a6105e53660046137e1565b6114fc565b3480156105f657600080fd5b5061060a6106053660046134a2565b61157e565b60405161026191906138f1565b34801561062357600080fd5b5061028a6106323660046134a2565b6116b0565b34801561064357600080fd5b50610657610652366004613624565b611755565b60405161026196959493929190613914565b34801561067557600080fd5b506106896106843660046134a2565b611819565b6040516102619796959493929190613955565b3480156106a857600080fd5b5061028a6106b73660046139a9565b6118fa565b3480156106c857600080fd5b5061030f6106d7366004613624565b6101346020526000908152604090205481565b61030f6106f8366004613a25565b611c1e565b34801561070957600080fd5b5061071d6107183660046134a2565b611e1e565b604051610261929190613b02565b34801561073757600080fd5b5061028a61074636600461365a565b61209a565b34801561075757600080fd5b5061076b610766366004613624565b6120bf565b6040516102619190613b27565b34801561078457600080fd5b5061028a61079336600461363d565b612253565b3480156107a457600080fd5b5061030f61012e5481565b3480156107bb57600080fd5b506102556107ca36600461363d565b6001600160a01b03166000908152610135602052604090205460ff1690565b60006001600160e01b03198216637965db0b60e01b148061081a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61012f5482906001600160a01b0316632fa117e58261083d6122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610887573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ab9190613b3a565b6108d05760405162461bcd60e51b81526004016108c790613b57565b60405180910390fd5b600082815261013160205260409020600181015484146109225760405162461bcd60e51b815260206004820152600d60248201526c3737ba103a34329037bbb732b960991b60448201526064016108c7565b6000815460ff16600481111561093a5761093a61380d565b1461097f5760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108c7565b805460ff191660031781556040518381527f853aa4be1ac86f37acfc91d42b57f1fe895205aa6f8f9b7caa77ca257049ab1a9060200160405180910390a150505050565b61012f5484906001600160a01b0316632fa117e5826109e06122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610a2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4e9190613b3a565b610a6a5760405162461bcd60e51b81526004016108c790613b57565b60008481526101316020526040902060018101548614610abc5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108c7565b6000815460ff166004811115610ad457610ad461380d565b14610b195760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108c7565b602e8314610b395760405162461bcd60e51b81526004016108c790613b86565b60038101610b48848683613c2b565b50847f1cae99404f615a4039d85b1009cb70622aae6d64f671e8b1b191d9269847d43e8585604051610b7b929190613d15565b60405180910390a2505050505050565b61012f548a906001600160a01b0316632fa117e582610ba86122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610bf2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c169190613b3a565b610c325760405162461bcd60e51b81526004016108c790613b57565b610c438b8b8b8b8b8b8b8a8a6122d8565b6040805160e0810190915280600081526020018c81526020018a6001600160a01b0316815260200189815260200188815260200187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093855250505060209182018790528c8152610132825260408082208f83529092522081518154829060ff191660018381811115610ce857610ce861380d565b02179055506020820151600182015560408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a08201516005820190610d459082613d31565b5060c0919091015160069091015560008b81526101336020526040902054158015610d7d575060008b81526101346020526040902054155b15610de25761012f546040516383ce205b60e01b8152600481018d90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015610dc957600080fd5b505af1158015610ddd573d6000803e3d6000fd5b505050505b60008b815261013460205260408120805491610dfd83613e07565b91905055507f11a8bc6241aa94a07af6c545ce8ed2dca2aaede88d02fd2b7e2d7ed28ccf1d4a8a8c888860008e8e8e8c604051610e4299989796959493929190613e20565b60405180910390a15050505050505050505050565b610e5f6126a7565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b600082815260fc6020526040902060010154610ed581612720565b610edf8383612731565b505050565b610eec6122c9565b6001600160a01b0316816001600160a01b031614610f645760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108c7565b610f6e82826127b8565b5050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610fba5760405162461bcd60e51b81526004016108c790613e81565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166110036000805160206141b4833981519152546001600160a01b031690565b6001600160a01b0316146110295760405162461bcd60e51b81526004016108c790613ecd565b6110328161283d565b6040805160008082526020820190925261104e91839190612845565b50565b6110596126a7565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee69101610eaf565b60006110b581612720565b6101368290556040518281527f577d7afcf67637a2f602cba220bbb292c1d715380dd011bfec748c3f641b2fd29060200160405180910390a15050565b600054610100900460ff16158080156111125750600054600160ff909116105b8061112c5750303b15801561112c575060005460ff166001145b61118f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108c7565b6000805460ff1916600117905580156111b2576000805461ff0019166101001790555b6111ba6129b0565b6111c26129df565b6111ca6129df565b6111dc60006111d76122c9565b612a06565b61012f80546001600160a01b038086166001600160a01b031992831617909255610130805492851692909116919091179055600161012e5561121e601e6110aa565b8015610edf576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036112b15760405162461bcd60e51b81526004016108c790613e81565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166112fa6000805160206141b4833981519152546001600160a01b031690565b6001600160a01b0316146113205760405162461bcd60e51b81526004016108c790613ecd565b6113298261283d565b610f6e82826001612845565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146113d55760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108c7565b506000805160206141b483398151915290565b6113f06126a7565b6113fa6000612a10565b565b6114046126a7565b6001600160a01b038316158015611419575081155b156114665760405162461bcd60e51b815260206004820152601d60248201527f4f776e65722063616e27742072656d6f7665204f78206164647265737300000060448201526064016108c7565b6001600160a01b03831660008181526101356020908152604091829020805460ff19168615159081178255600190910185905582519384529083015281018290527f42b585a1da1cff4b571e7a78aea1b4601b1d128de41a0feebd8a77aaf48b9d889060600161125c565b600091825260fc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f61152681612720565b60008481526101316020908152604080832061013283528184208785529092529091208154600160ff1991821681178455808301546002850155600484018690558254909183911682805b0217905550505050505050565b611586613431565b60008381526101326020908152604080832085845290915290819020815160e081019092528054829060ff1660018111156115c3576115c361380d565b60018111156115d4576115d461380d565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a09092019161161c90613bab565b80601f016020809104026020016040519081016040528092919081815260200182805461164890613bab565b80156116955780601f1061166a57610100808354040283529160200191611695565b820191906000526020600020905b81548152906001019060200180831161167857829003601f168201915b50505050508152602001600682015481525050905092915050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f6116da81612720565b6000838152610131602090815260408083206101328352818420600282015485529092528220600381015491929091611714866064613f19565b61171e9190613f30565b905061013654811061173a57825460ff1916600217835561174d565b8254600490849060ff1916600183611571565b505050505050565b61013160205260009081526040902080546001820154600283015460038401805460ff90941694929391929161178a90613bab565b80601f01602080910402602001604051908101604052809291908181526020018280546117b690613bab565b80156118035780601f106117d857610100808354040283529160200191611803565b820191906000526020600020905b8154815290600101906020018083116117e657829003601f168201915b5050505050908060040154908060050154905086565b61013260209081526000928352604080842090915290825290208054600182015460028301546003840154600485015460058601805460ff9096169694956001600160a01b0390941694929391929161187190613bab565b80601f016020809104026020016040519081016040528092919081815260200182805461189d90613bab565b80156118ea5780601f106118bf576101008083540402835291602001916118ea565b820191906000526020600020905b8154815290600101906020018083116118cd57829003601f168201915b5050505050908060060154905087565b61012f5487906001600160a01b0316632fa117e5826119176122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611961573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119859190613b3a565b6119a15760405162461bcd60e51b81526004016108c790613b57565b6001600160a01b0386166000908152610135602052604090205460ff166119fe5760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108c7565b60008781526101316020908152604080832061013283528184208c855290925282209091825460ff166004811115611a3857611a3861380d565b14611a7a5760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108c7565b89816001015414611abd5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108c7565b602e8514611add5760405162461bcd60e51b81526004016108c790613b86565b6001815460ff166001811115611af557611af561380d565b03611b365760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481d985b1a59185d1959607a1b60448201526064016108c7565b6001600160a01b03881660009081526101356020526040902060010154871015611b935760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108c7565b6002810180546001600160a01b0319166001600160a01b038a161790556003810187905560058101611bc6868883613c2b565b50600681018490556040517f0f68ab04ab4935c8598d30f2c12ec34265575059bb4cae481b4d632cc43db81e90611c0a908b908d908a908a908e908e908c90613f52565b60405180910390a150505050505050505050565b61012f5460009087906001600160a01b0316632fa117e582611c3e6122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611c88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cac9190613b3a565b611cc85760405162461bcd60e51b81526004016108c790613b57565b611cd6888888888888612a62565b61012e80549081906000611ce983613e07565b9091555050600081815261013160205260409020805460ff19168155600181018a905560038101611d1b888a83613c2b565b506005810189905560008a81526101336020526040902054158015611d4d575060008a81526101346020526040902054155b15611db25761012f546040516383ce205b60e01b8152600481018c90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015611d9957600080fd5b505af1158015611dad573d6000803e3d6000fd5b505050505b60008a815261013360205260408120805491611dcd83613e07565b91905055507f8f3fc1086abc1020f602edd700a9ae5801b250c9d110af9e54022d7cc5df7bee828b8b8b8b604051611e09959493929190613f9a565b60405180910390a15098975050505050505050565b611e586040805160c08101909152806000815260200160008152602001600081526020016060815260200160008152602001600081525090565b611e60613431565b60008481526101316020526040808220815160c081019092528054829060ff166004811115611e9157611e9161380d565b6004811115611ea257611ea261380d565b81526020016001820154815260200160028201548152602001600382018054611eca90613bab565b80601f0160208091040260200160405190810160405280929190818152602001828054611ef690613bab565b8015611f435780601f10611f1857610100808354040283529160200191611f43565b820191906000526020600020905b815481529060010190602001808311611f2657829003601f168201915b5050509183525050600482015460208083019190915260059092015460409182015260008881526101328352818120888252909252808220815160e0810190925280549394509192909190829060ff166001811115611fa457611fa461380d565b6001811115611fb557611fb561380d565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611ffd90613bab565b80601f016020809104026020016040519081016040528092919081815260200182805461202990613bab565b80156120765780601f1061204b57610100808354040283529160200191612076565b820191906000526020600020905b81548152906001019060200180831161205957829003601f168201915b505050918352505060069190910154602090910152919350909150505b9250929050565b600082815260fc60205260409020600101546120b581612720565b610edf83836127b8565b6120f96040805160c08101909152806000815260200160008152602001600081526020016060815260200160008152602001600081525090565b61012e54821061214b5760405162461bcd60e51b815260206004820152601a60248201527f54686973207365727669636520646f65736e277420657869737400000000000060448201526064016108c7565b6000828152610131602052604090819020815160c081019092528054829060ff16600481111561217d5761217d61380d565b600481111561218e5761218e61380d565b815260200160018201548152602001600282015481526020016003820180546121b690613bab565b80601f01602080910402602001604051908101604052809291908181526020018280546121e290613bab565b801561222f5780601f106122045761010080835404028352916020019161222f565b820191906000526020600020905b81548152906001019060200180831161221257829003601f168201915b50505050508152602001600482015481526020016005820154815250509050919050565b61225b6126a7565b6001600160a01b0381166122c05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108c7565b61104e81612a10565b60006122d3612c0d565b905090565b6001600160a01b0387166000908152610135602052604090205460ff166123355760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108c7565b61013054604051634a7ab1d560e01b8152600481018790526000916001600160a01b031690634a7ab1d590602401602060405180830381865afa158015612380573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a49190613fcb565b90508034146123ea5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108c7565b6001600160a01b038816600090815261013560205260409020600101548710156124475760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108c7565b60008981526101316020526040812090815460ff16600481111561246d5761246d61380d565b146124af5760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108c7565b80600101546000036124f75760405162461bcd60e51b815260206004820152601160248201527014d95c9d9a58d9481b9bdd08195e1a5cdd607a1b60448201526064016108c7565b60008a8152610132602090815260408083208e84529091529020600101548b900361255d5760405162461bcd60e51b81526020600482015260166024820152751c1c9bdc1bdcd85b08185b1c9958591e48195e1a5cdd60521b60448201526064016108c7565b8a8160010154036125ba5760405162461bcd60e51b815260206004820152602160248201527f63616e27742063726561746520666f7220796f7572206f776e207365727669636044820152606560f81b60648201526084016108c7565b602e85146125da5760405162461bcd60e51b81526004016108c790613b86565b61013054604051631fff7f2760e11b8152600481018990526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612625573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126499190613fe4565b90506001600160a01b038116156126995760008c8c89896040516020016126739493929190614001565b60405160208183030381529060405280519060200120905061269786868385612c46565b505b505050505050505050505050565b6126af6122c9565b6001600160a01b03166126ca6033546001600160a01b031690565b6001600160a01b0316146113fa5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108c7565b61104e8161272c6122c9565b612d3a565b61273b82826114d1565b610f6e57600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191660011790556127746122c9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6127c282826114d1565b15610f6e57600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191690556127f96122c9565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b61104e6126a7565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561287857610edf83612d93565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156128d2575060408051601f3d908101601f191682019092526128cf91810190613fcb565b60015b6129355760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108c7565b6000805160206141b483398151915281146129a45760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108c7565b50610edf838383612e2f565b600054610100900460ff166129d75760405162461bcd60e51b81526004016108c790614043565b6113fa612e5a565b600054610100900460ff166113fa5760405162461bcd60e51b81526004016108c790614043565b610f6e8282612731565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61013054604051638a98636360e01b8152600481018790526000916001600160a01b031690638a98636390602401602060405180830381865afa158015612aad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ad19190613fcb565b9050803414612b175760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108c7565b602e8414612b375760405162461bcd60e51b81526004016108c790613b86565b61013054604051631fff7f2760e11b8152600481018890526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612b82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ba69190613fe4565b90506001600160a01b03811615612c0357600088815261013360209081526040808320549051612bdd928c92918b918b910161408e565b604051602081830303815290604052805190602001209050612c0185858385612c46565b505b5050505050505050565b600060143610801590612c2f57503360009081526065602052604090205460ff165b15612c41575060131936013560601c90565b503390565b6000612c9f836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000612ce38287878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9192505050565b9050806001600160a01b0316836001600160a01b03161461174d5760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064016108c7565b612d4482826114d1565b610f6e57612d5181612eb5565b612d5c836020612ec7565b604051602001612d6d9291906140cf565b60408051601f198184030181529082905262461bcd60e51b82526108c791600401614144565b6001600160a01b0381163b612e005760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108c7565b6000805160206141b483398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b612e388361306a565b600082511180612e455750805b15610edf57612e5483836130aa565b50505050565b600054610100900460ff16612e815760405162461bcd60e51b81526004016108c790614043565b6113fa612e8c6122c9565b612a10565b6000806000612ea0858561319e565b91509150612ead816131e0565b509392505050565b606061081a6001600160a01b03831660145b60606000612ed6836002613f19565b612ee1906002614157565b67ffffffffffffffff811115612ef957612ef96136b8565b6040519080825280601f01601f191660200182016040528015612f23576020820181803683370190505b509050600360fc1b81600081518110612f3e57612f3e61416a565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612f6d57612f6d61416a565b60200101906001600160f81b031916908160001a9053506000612f91846002613f19565b612f9c906001614157565b90505b6001811115613014576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612fd057612fd061416a565b1a60f81b828281518110612fe657612fe661416a565b60200101906001600160f81b031916908160001a90535060049490941c9361300d81614180565b9050612f9f565b5083156130635760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108c7565b9392505050565b61307381612d93565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6131125760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108c7565b600080846001600160a01b03168460405161312d9190614197565b600060405180830381855af49150503d8060008114613168576040519150601f19603f3d011682016040523d82523d6000602084013e61316d565b606091505b509150915061319582826040518060600160405280602781526020016141d46027913961332a565b95945050505050565b60008082516041036131d45760208301516040840151606085015160001a6131c887828585613343565b94509450505050612093565b50600090506002612093565b60008160048111156131f4576131f461380d565b036131fc5750565b60018160048111156132105761321061380d565b0361325d5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108c7565b60028160048111156132715761327161380d565b036132be5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108c7565b60038160048111156132d2576132d261380d565b0361104e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108c7565b60608315613339575081613063565b6130638383613407565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561337a57506000905060036133fe565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156133ce573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166133f7576000600192509250506133fe565b9150600090505b94509492505050565b8151156134175781518083602001fd5b8060405162461bcd60e51b81526004016108c79190614144565b6040805160e0810190915280600081526020016000815260200160006001600160a01b03168152602001600081526020016000815260200160608152602001600081525090565b60006020828403121561348a57600080fd5b81356001600160e01b03198116811461306357600080fd5b600080604083850312156134b557600080fd5b50508035926020909101359150565b60008083601f8401126134d657600080fd5b50813567ffffffffffffffff8111156134ee57600080fd5b60208301915083602082850101111561209357600080fd5b6000806000806060858703121561351c57600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561354157600080fd5b61354d878288016134c4565b95989497509550505050565b6001600160a01b038116811461104e57600080fd5b6000806000806000806000806000806101008b8d03121561358e57600080fd5b8a35995060208b0135985060408b01356135a781613559565b975060608b0135965060808b0135955060a08b013567ffffffffffffffff808211156135d257600080fd5b6135de8e838f016134c4565b909750955060c08d0135945060e08d01359150808211156135fe57600080fd5b5061360b8d828e016134c4565b915080935050809150509295989b9194979a5092959850565b60006020828403121561363657600080fd5b5035919050565b60006020828403121561364f57600080fd5b813561306381613559565b6000806040838503121561366d57600080fd5b82359150602083013561367f81613559565b809150509250929050565b6000806040838503121561369d57600080fd5b82356136a881613559565b9150602083013561367f81613559565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156136e157600080fd5b82356136ec81613559565b9150602083013567ffffffffffffffff8082111561370957600080fd5b818501915085601f83011261371d57600080fd5b81358181111561372f5761372f6136b8565b604051601f8201601f19908116603f01168101908382118183101715613757576137576136b8565b8160405282815288602084870101111561377057600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b801515811461104e57600080fd5b6000806000606084860312156137b557600080fd5b83356137c081613559565b925060208401356137d081613792565b929592945050506040919091013590565b6000806000606084860312156137f657600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052602160045260246000fd5b600281106138335761383361380d565b9052565b60005b8381101561385257818101518382015260200161383a565b50506000910152565b60008151808452613873816020860160208601613837565b601f01601f19169290920160200192915050565b613892828251613823565b6020810151602083015260018060a01b0360408201511660408301526060810151606083015260808101516080830152600060a082015160e060a08501526138dd60e085018261385b565b60c093840151949093019390935250919050565b6020815260006130636020830184613887565b600581106138335761383361380d565b61391e8188613904565b85602082015284604082015260c06060820152600061394060c083018661385b565b60808301949094525060a00152949350505050565b61395f8189613823565b86602082015260018060a01b038616604082015284606082015283608082015260e060a0820152600061399560e083018561385b565b90508260c083015298975050505050505050565b600080600080600080600060c0888a0312156139c457600080fd5b873596506020880135955060408801356139dd81613559565b945060608801359350608088013567ffffffffffffffff811115613a0057600080fd5b613a0c8a828b016134c4565b989b979a5095989497959660a090950135949350505050565b60008060008060008060808789031215613a3e57600080fd5b8635955060208701359450604087013567ffffffffffffffff80821115613a6457600080fd5b613a708a838b016134c4565b90965094506060890135915080821115613a8957600080fd5b50613a9689828a016134c4565b979a9699509497509295939492505050565b613ab3828251613904565b60208101516020830152604081015160408301526000606082015160c06060850152613ae260c085018261385b565b90506080830151608085015260a083015160a08501528091505092915050565b604081526000613b156040830185613aa8565b82810360208401526131958185613887565b6020815260006130636020830184613aa8565b600060208284031215613b4c57600080fd5b815161306381613792565b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b6020808252600b908201526a125b9d985b1a590818da5960aa1b604082015260600190565b600181811c90821680613bbf57607f821691505b602082108103613bdf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610edf57600081815260208120601f850160051c81016020861015613c0c5750805b601f850160051c820191505b8181101561174d57828155600101613c18565b67ffffffffffffffff831115613c4357613c436136b8565b613c5783613c518354613bab565b83613be5565b6000601f841160018114613c8b5760008515613c735750838201355b600019600387901b1c1916600186901b178355613ce5565b600083815260209020601f19861690835b82811015613cbc5786850135825560209485019460019092019101613c9c565b5086821015613cd95760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000613d29602083018486613cec565b949350505050565b815167ffffffffffffffff811115613d4b57613d4b6136b8565b613d5f81613d598454613bab565b84613be5565b602080601f831160018114613d945760008415613d7c5750858301515b600019600386901b1c1916600185901b17855561174d565b600085815260208120601f198616915b82811015613dc357888601518255948401946001909101908401613da4565b5085821015613de15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b600060018201613e1957613e19613df1565b5060010190565b60006101008b83528a6020840152806040840152613e418184018a8c613cec565b915050613e516060830188613823565b6001600160a01b0395909516608082015260a081019390935260c083019190915260e09091015295945050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b808202811582820484141761081a5761081a613df1565b600082613f4d57634e487b7160e01b600052601260045260246000fd5b500490565b87815286602082015260c060408201526000613f7260c083018789613cec565b6001600160a01b0395909516606083015250608081019290925260a090910152949350505050565b858152846020820152836040820152608060608201526000613fc0608083018486613cec565b979650505050505050565b600060208284031215613fdd57600080fd5b5051919050565b600060208284031215613ff657600080fd5b815161306381613559565b6d18dc99585d19541c9bdc1bdcd85b60921b815284600e820152603b60f81b602e82015283602f8201528183604f83013760009101604f019081529392505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6c6372656174655365727669636560981b815284600d820152603b60f81b602d82015283602e8201528183604e83013760009101604e019081529392505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614107816017850160208801613837565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351614138816028840160208801613837565b01602801949350505050565b602081526000613063602083018461385b565b8082018082111561081a5761081a613df1565b634e487b7160e01b600052603260045260246000fd5b60008161418f5761418f613df1565b506000190190565b600082516141a9818460208701613837565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220810e0f3326770d5cbf2063fa706b979e196534c448759006348f0d89ef76705a64736f6c63430008110033", - "deployedBytecode": "0x6080604052600436106102305760003560e01c8063715018a61161012e578063c2cfee27116100ab578063d547741f1161006f578063d547741f1461072b578063ef0e239b1461074b578063f2fde38b14610778578063f6c53d9b14610798578063f9eaee0d146107af57600080fd5b8063c2cfee2714610669578063c75858d51461069c578063ccaa7d2a146106bc578063d338ec9a146106ea578063d4eee1fc146106fd57600080fd5b8063a217fddf116100f2578063a217fddf146105b5578063a7d5eaea146105ca578063aba21009146105ea578063b5735c1e14610617578063c22c4f431461063757600080fd5b8063715018a6146104f057806371da85f9146105055780637c5a72cd146105575780638da5cb5b1461057757806391d148541461059557600080fd5b80632f2ff15d116101bc578063485cc95511610180578063485cc9551461043b5780634f1ef2861461045b57806352d1902d1461046e578063572b6c05146104835780636ce76f30146104bc57600080fd5b80632f2ff15d1461039b57806336568abe146103bb5780633659cfe6146103db5780633751d89c146103fb5780633ca2ad6f1461041b57600080fd5b80631499f9e6116102035780631499f9e6146102bf578063156b39aa146102f85780631db087ff1461031d578063248a9ca31461034b57806326d006681461037b57600080fd5b806301ffc9a714610235578063089b7c731461026a5780630e0660251461028c57806313ca98db146102ac575b600080fd5b34801561024157600080fd5b50610255610250366004613478565b6107e9565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061028a6102853660046134a2565b610820565b005b34801561029857600080fd5b5061028a6102a7366004613506565b6109c3565b61028a6102ba36600461356e565b610b8b565b3480156102cb57600080fd5b50610130546102e0906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b34801561030457600080fd5b5061030f6101365481565b604051908152602001610261565b34801561032957600080fd5b5061030f610338366004613624565b6101336020526000908152604090205481565b34801561035757600080fd5b5061030f610366366004613624565b600090815260fc602052604090206001015490565b34801561038757600080fd5b5061028a61039636600461363d565b610e57565b3480156103a757600080fd5b5061028a6103b636600461365a565b610eba565b3480156103c757600080fd5b5061028a6103d636600461365a565b610ee4565b3480156103e757600080fd5b5061028a6103f636600461363d565b610f72565b34801561040757600080fd5b5061028a61041636600461363d565b611051565b34801561042757600080fd5b5061028a610436366004613624565b6110aa565b34801561044757600080fd5b5061028a61045636600461368a565b6110f2565b61028a6104693660046136ce565b611269565b34801561047a57600080fd5b5061030f611335565b34801561048f57600080fd5b5061025561049e36600461363d565b6001600160a01b031660009081526065602052604090205460ff1690565b3480156104c857600080fd5b5061030f7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f81565b3480156104fc57600080fd5b5061028a6113e8565b34801561051157600080fd5b5061054061052036600461363d565b610135602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610261565b34801561056357600080fd5b5061028a6105723660046137a0565b6113fc565b34801561058357600080fd5b506033546001600160a01b03166102e0565b3480156105a157600080fd5b506102556105b036600461365a565b6114d1565b3480156105c157600080fd5b5061030f600081565b3480156105d657600080fd5b5061028a6105e53660046137e1565b6114fc565b3480156105f657600080fd5b5061060a6106053660046134a2565b61157e565b60405161026191906138f1565b34801561062357600080fd5b5061028a6106323660046134a2565b6116b0565b34801561064357600080fd5b50610657610652366004613624565b611755565b60405161026196959493929190613914565b34801561067557600080fd5b506106896106843660046134a2565b611819565b6040516102619796959493929190613955565b3480156106a857600080fd5b5061028a6106b73660046139a9565b6118fa565b3480156106c857600080fd5b5061030f6106d7366004613624565b6101346020526000908152604090205481565b61030f6106f8366004613a25565b611c1e565b34801561070957600080fd5b5061071d6107183660046134a2565b611e1e565b604051610261929190613b02565b34801561073757600080fd5b5061028a61074636600461365a565b61209a565b34801561075757600080fd5b5061076b610766366004613624565b6120bf565b6040516102619190613b27565b34801561078457600080fd5b5061028a61079336600461363d565b612253565b3480156107a457600080fd5b5061030f61012e5481565b3480156107bb57600080fd5b506102556107ca36600461363d565b6001600160a01b03166000908152610135602052604090205460ff1690565b60006001600160e01b03198216637965db0b60e01b148061081a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61012f5482906001600160a01b0316632fa117e58261083d6122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610887573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ab9190613b3a565b6108d05760405162461bcd60e51b81526004016108c790613b57565b60405180910390fd5b600082815261013160205260409020600181015484146109225760405162461bcd60e51b815260206004820152600d60248201526c3737ba103a34329037bbb732b960991b60448201526064016108c7565b6000815460ff16600481111561093a5761093a61380d565b1461097f5760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108c7565b805460ff191660031781556040518381527f853aa4be1ac86f37acfc91d42b57f1fe895205aa6f8f9b7caa77ca257049ab1a9060200160405180910390a150505050565b61012f5484906001600160a01b0316632fa117e5826109e06122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610a2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4e9190613b3a565b610a6a5760405162461bcd60e51b81526004016108c790613b57565b60008481526101316020526040902060018101548614610abc5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108c7565b6000815460ff166004811115610ad457610ad461380d565b14610b195760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108c7565b602e8314610b395760405162461bcd60e51b81526004016108c790613b86565b60038101610b48848683613c2b565b50847f1cae99404f615a4039d85b1009cb70622aae6d64f671e8b1b191d9269847d43e8585604051610b7b929190613d15565b60405180910390a2505050505050565b61012f548a906001600160a01b0316632fa117e582610ba86122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610bf2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c169190613b3a565b610c325760405162461bcd60e51b81526004016108c790613b57565b610c438b8b8b8b8b8b8b8a8a6122d8565b6040805160e0810190915280600081526020018c81526020018a6001600160a01b0316815260200189815260200188815260200187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093855250505060209182018790528c8152610132825260408082208f83529092522081518154829060ff191660018381811115610ce857610ce861380d565b02179055506020820151600182015560408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a08201516005820190610d459082613d31565b5060c0919091015160069091015560008b81526101336020526040902054158015610d7d575060008b81526101346020526040902054155b15610de25761012f546040516383ce205b60e01b8152600481018d90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015610dc957600080fd5b505af1158015610ddd573d6000803e3d6000fd5b505050505b60008b815261013460205260408120805491610dfd83613e07565b91905055507f11a8bc6241aa94a07af6c545ce8ed2dca2aaede88d02fd2b7e2d7ed28ccf1d4a8a8c888860008e8e8e8c604051610e4299989796959493929190613e20565b60405180910390a15050505050505050505050565b610e5f6126a7565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b600082815260fc6020526040902060010154610ed581612720565b610edf8383612731565b505050565b610eec6122c9565b6001600160a01b0316816001600160a01b031614610f645760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108c7565b610f6e82826127b8565b5050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610fba5760405162461bcd60e51b81526004016108c790613e81565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166110036000805160206141b4833981519152546001600160a01b031690565b6001600160a01b0316146110295760405162461bcd60e51b81526004016108c790613ecd565b6110328161283d565b6040805160008082526020820190925261104e91839190612845565b50565b6110596126a7565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee69101610eaf565b60006110b581612720565b6101368290556040518281527f577d7afcf67637a2f602cba220bbb292c1d715380dd011bfec748c3f641b2fd29060200160405180910390a15050565b600054610100900460ff16158080156111125750600054600160ff909116105b8061112c5750303b15801561112c575060005460ff166001145b61118f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108c7565b6000805460ff1916600117905580156111b2576000805461ff0019166101001790555b6111ba6129b0565b6111c26129df565b6111ca6129df565b6111dc60006111d76122c9565b612a06565b61012f80546001600160a01b038086166001600160a01b031992831617909255610130805492851692909116919091179055600161012e5561121e601e6110aa565b8015610edf576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036112b15760405162461bcd60e51b81526004016108c790613e81565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166112fa6000805160206141b4833981519152546001600160a01b031690565b6001600160a01b0316146113205760405162461bcd60e51b81526004016108c790613ecd565b6113298261283d565b610f6e82826001612845565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146113d55760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108c7565b506000805160206141b483398151915290565b6113f06126a7565b6113fa6000612a10565b565b6114046126a7565b6001600160a01b038316158015611419575081155b156114665760405162461bcd60e51b815260206004820152601d60248201527f4f776e65722063616e27742072656d6f7665204f78206164647265737300000060448201526064016108c7565b6001600160a01b03831660008181526101356020908152604091829020805460ff19168615159081178255600190910185905582519384529083015281018290527f42b585a1da1cff4b571e7a78aea1b4601b1d128de41a0feebd8a77aaf48b9d889060600161125c565b600091825260fc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f61152681612720565b60008481526101316020908152604080832061013283528184208785529092529091208154600160ff1991821681178455808301546002850155600484018690558254909183911682805b0217905550505050505050565b611586613431565b60008381526101326020908152604080832085845290915290819020815160e081019092528054829060ff1660018111156115c3576115c361380d565b60018111156115d4576115d461380d565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a09092019161161c90613bab565b80601f016020809104026020016040519081016040528092919081815260200182805461164890613bab565b80156116955780601f1061166a57610100808354040283529160200191611695565b820191906000526020600020905b81548152906001019060200180831161167857829003601f168201915b50505050508152602001600682015481525050905092915050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f6116da81612720565b6000838152610131602090815260408083206101328352818420600282015485529092528220600381015491929091611714866064613f19565b61171e9190613f30565b905061013654811061173a57825460ff1916600217835561174d565b8254600490849060ff1916600183611571565b505050505050565b61013160205260009081526040902080546001820154600283015460038401805460ff90941694929391929161178a90613bab565b80601f01602080910402602001604051908101604052809291908181526020018280546117b690613bab565b80156118035780601f106117d857610100808354040283529160200191611803565b820191906000526020600020905b8154815290600101906020018083116117e657829003601f168201915b5050505050908060040154908060050154905086565b61013260209081526000928352604080842090915290825290208054600182015460028301546003840154600485015460058601805460ff9096169694956001600160a01b0390941694929391929161187190613bab565b80601f016020809104026020016040519081016040528092919081815260200182805461189d90613bab565b80156118ea5780601f106118bf576101008083540402835291602001916118ea565b820191906000526020600020905b8154815290600101906020018083116118cd57829003601f168201915b5050505050908060060154905087565b61012f5487906001600160a01b0316632fa117e5826119176122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611961573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119859190613b3a565b6119a15760405162461bcd60e51b81526004016108c790613b57565b6001600160a01b0386166000908152610135602052604090205460ff166119fe5760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108c7565b60008781526101316020908152604080832061013283528184208c855290925282209091825460ff166004811115611a3857611a3861380d565b14611a7a5760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108c7565b89816001015414611abd5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108c7565b602e8514611add5760405162461bcd60e51b81526004016108c790613b86565b6001815460ff166001811115611af557611af561380d565b03611b365760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481d985b1a59185d1959607a1b60448201526064016108c7565b6001600160a01b03881660009081526101356020526040902060010154871015611b935760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108c7565b6002810180546001600160a01b0319166001600160a01b038a161790556003810187905560058101611bc6868883613c2b565b50600681018490556040517f0f68ab04ab4935c8598d30f2c12ec34265575059bb4cae481b4d632cc43db81e90611c0a908b908d908a908a908e908e908c90613f52565b60405180910390a150505050505050505050565b61012f5460009087906001600160a01b0316632fa117e582611c3e6122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611c88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cac9190613b3a565b611cc85760405162461bcd60e51b81526004016108c790613b57565b611cd6888888888888612a62565b61012e80549081906000611ce983613e07565b9091555050600081815261013160205260409020805460ff19168155600181018a905560038101611d1b888a83613c2b565b506005810189905560008a81526101336020526040902054158015611d4d575060008a81526101346020526040902054155b15611db25761012f546040516383ce205b60e01b8152600481018c90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015611d9957600080fd5b505af1158015611dad573d6000803e3d6000fd5b505050505b60008a815261013360205260408120805491611dcd83613e07565b91905055507f8f3fc1086abc1020f602edd700a9ae5801b250c9d110af9e54022d7cc5df7bee828b8b8b8b604051611e09959493929190613f9a565b60405180910390a15098975050505050505050565b611e586040805160c08101909152806000815260200160008152602001600081526020016060815260200160008152602001600081525090565b611e60613431565b60008481526101316020526040808220815160c081019092528054829060ff166004811115611e9157611e9161380d565b6004811115611ea257611ea261380d565b81526020016001820154815260200160028201548152602001600382018054611eca90613bab565b80601f0160208091040260200160405190810160405280929190818152602001828054611ef690613bab565b8015611f435780601f10611f1857610100808354040283529160200191611f43565b820191906000526020600020905b815481529060010190602001808311611f2657829003601f168201915b5050509183525050600482015460208083019190915260059092015460409182015260008881526101328352818120888252909252808220815160e0810190925280549394509192909190829060ff166001811115611fa457611fa461380d565b6001811115611fb557611fb561380d565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611ffd90613bab565b80601f016020809104026020016040519081016040528092919081815260200182805461202990613bab565b80156120765780601f1061204b57610100808354040283529160200191612076565b820191906000526020600020905b81548152906001019060200180831161205957829003601f168201915b505050918352505060069190910154602090910152919350909150505b9250929050565b600082815260fc60205260409020600101546120b581612720565b610edf83836127b8565b6120f96040805160c08101909152806000815260200160008152602001600081526020016060815260200160008152602001600081525090565b61012e54821061214b5760405162461bcd60e51b815260206004820152601a60248201527f54686973207365727669636520646f65736e277420657869737400000000000060448201526064016108c7565b6000828152610131602052604090819020815160c081019092528054829060ff16600481111561217d5761217d61380d565b600481111561218e5761218e61380d565b815260200160018201548152602001600282015481526020016003820180546121b690613bab565b80601f01602080910402602001604051908101604052809291908181526020018280546121e290613bab565b801561222f5780601f106122045761010080835404028352916020019161222f565b820191906000526020600020905b81548152906001019060200180831161221257829003601f168201915b50505050508152602001600482015481526020016005820154815250509050919050565b61225b6126a7565b6001600160a01b0381166122c05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108c7565b61104e81612a10565b60006122d3612c0d565b905090565b6001600160a01b0387166000908152610135602052604090205460ff166123355760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108c7565b61013054604051634a7ab1d560e01b8152600481018790526000916001600160a01b031690634a7ab1d590602401602060405180830381865afa158015612380573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a49190613fcb565b90508034146123ea5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108c7565b6001600160a01b038816600090815261013560205260409020600101548710156124475760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108c7565b60008981526101316020526040812090815460ff16600481111561246d5761246d61380d565b146124af5760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108c7565b80600101546000036124f75760405162461bcd60e51b815260206004820152601160248201527014d95c9d9a58d9481b9bdd08195e1a5cdd607a1b60448201526064016108c7565b60008a8152610132602090815260408083208e84529091529020600101548b900361255d5760405162461bcd60e51b81526020600482015260166024820152751c1c9bdc1bdcd85b08185b1c9958591e48195e1a5cdd60521b60448201526064016108c7565b8a8160010154036125ba5760405162461bcd60e51b815260206004820152602160248201527f63616e27742063726561746520666f7220796f7572206f776e207365727669636044820152606560f81b60648201526084016108c7565b602e85146125da5760405162461bcd60e51b81526004016108c790613b86565b61013054604051631fff7f2760e11b8152600481018990526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612625573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126499190613fe4565b90506001600160a01b038116156126995760008c8c89896040516020016126739493929190614001565b60405160208183030381529060405280519060200120905061269786868385612c46565b505b505050505050505050505050565b6126af6122c9565b6001600160a01b03166126ca6033546001600160a01b031690565b6001600160a01b0316146113fa5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108c7565b61104e8161272c6122c9565b612d3a565b61273b82826114d1565b610f6e57600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191660011790556127746122c9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6127c282826114d1565b15610f6e57600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191690556127f96122c9565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b61104e6126a7565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561287857610edf83612d93565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156128d2575060408051601f3d908101601f191682019092526128cf91810190613fcb565b60015b6129355760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108c7565b6000805160206141b483398151915281146129a45760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108c7565b50610edf838383612e2f565b600054610100900460ff166129d75760405162461bcd60e51b81526004016108c790614043565b6113fa612e5a565b600054610100900460ff166113fa5760405162461bcd60e51b81526004016108c790614043565b610f6e8282612731565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61013054604051638a98636360e01b8152600481018790526000916001600160a01b031690638a98636390602401602060405180830381865afa158015612aad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ad19190613fcb565b9050803414612b175760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108c7565b602e8414612b375760405162461bcd60e51b81526004016108c790613b86565b61013054604051631fff7f2760e11b8152600481018890526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612b82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ba69190613fe4565b90506001600160a01b03811615612c0357600088815261013360209081526040808320549051612bdd928c92918b918b910161408e565b604051602081830303815290604052805190602001209050612c0185858385612c46565b505b5050505050505050565b600060143610801590612c2f57503360009081526065602052604090205460ff165b15612c41575060131936013560601c90565b503390565b6000612c9f836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000612ce38287878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9192505050565b9050806001600160a01b0316836001600160a01b03161461174d5760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064016108c7565b612d4482826114d1565b610f6e57612d5181612eb5565b612d5c836020612ec7565b604051602001612d6d9291906140cf565b60408051601f198184030181529082905262461bcd60e51b82526108c791600401614144565b6001600160a01b0381163b612e005760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108c7565b6000805160206141b483398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b612e388361306a565b600082511180612e455750805b15610edf57612e5483836130aa565b50505050565b600054610100900460ff16612e815760405162461bcd60e51b81526004016108c790614043565b6113fa612e8c6122c9565b612a10565b6000806000612ea0858561319e565b91509150612ead816131e0565b509392505050565b606061081a6001600160a01b03831660145b60606000612ed6836002613f19565b612ee1906002614157565b67ffffffffffffffff811115612ef957612ef96136b8565b6040519080825280601f01601f191660200182016040528015612f23576020820181803683370190505b509050600360fc1b81600081518110612f3e57612f3e61416a565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612f6d57612f6d61416a565b60200101906001600160f81b031916908160001a9053506000612f91846002613f19565b612f9c906001614157565b90505b6001811115613014576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612fd057612fd061416a565b1a60f81b828281518110612fe657612fe661416a565b60200101906001600160f81b031916908160001a90535060049490941c9361300d81614180565b9050612f9f565b5083156130635760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108c7565b9392505050565b61307381612d93565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6131125760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108c7565b600080846001600160a01b03168460405161312d9190614197565b600060405180830381855af49150503d8060008114613168576040519150601f19603f3d011682016040523d82523d6000602084013e61316d565b606091505b509150915061319582826040518060600160405280602781526020016141d46027913961332a565b95945050505050565b60008082516041036131d45760208301516040840151606085015160001a6131c887828585613343565b94509450505050612093565b50600090506002612093565b60008160048111156131f4576131f461380d565b036131fc5750565b60018160048111156132105761321061380d565b0361325d5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108c7565b60028160048111156132715761327161380d565b036132be5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108c7565b60038160048111156132d2576132d261380d565b0361104e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108c7565b60608315613339575081613063565b6130638383613407565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561337a57506000905060036133fe565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156133ce573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166133f7576000600192509250506133fe565b9150600090505b94509492505050565b8151156134175781518083602001fd5b8060405162461bcd60e51b81526004016108c79190614144565b6040805160e0810190915280600081526020016000815260200160006001600160a01b03168152602001600081526020016000815260200160608152602001600081525090565b60006020828403121561348a57600080fd5b81356001600160e01b03198116811461306357600080fd5b600080604083850312156134b557600080fd5b50508035926020909101359150565b60008083601f8401126134d657600080fd5b50813567ffffffffffffffff8111156134ee57600080fd5b60208301915083602082850101111561209357600080fd5b6000806000806060858703121561351c57600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561354157600080fd5b61354d878288016134c4565b95989497509550505050565b6001600160a01b038116811461104e57600080fd5b6000806000806000806000806000806101008b8d03121561358e57600080fd5b8a35995060208b0135985060408b01356135a781613559565b975060608b0135965060808b0135955060a08b013567ffffffffffffffff808211156135d257600080fd5b6135de8e838f016134c4565b909750955060c08d0135945060e08d01359150808211156135fe57600080fd5b5061360b8d828e016134c4565b915080935050809150509295989b9194979a5092959850565b60006020828403121561363657600080fd5b5035919050565b60006020828403121561364f57600080fd5b813561306381613559565b6000806040838503121561366d57600080fd5b82359150602083013561367f81613559565b809150509250929050565b6000806040838503121561369d57600080fd5b82356136a881613559565b9150602083013561367f81613559565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156136e157600080fd5b82356136ec81613559565b9150602083013567ffffffffffffffff8082111561370957600080fd5b818501915085601f83011261371d57600080fd5b81358181111561372f5761372f6136b8565b604051601f8201601f19908116603f01168101908382118183101715613757576137576136b8565b8160405282815288602084870101111561377057600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b801515811461104e57600080fd5b6000806000606084860312156137b557600080fd5b83356137c081613559565b925060208401356137d081613792565b929592945050506040919091013590565b6000806000606084860312156137f657600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052602160045260246000fd5b600281106138335761383361380d565b9052565b60005b8381101561385257818101518382015260200161383a565b50506000910152565b60008151808452613873816020860160208601613837565b601f01601f19169290920160200192915050565b613892828251613823565b6020810151602083015260018060a01b0360408201511660408301526060810151606083015260808101516080830152600060a082015160e060a08501526138dd60e085018261385b565b60c093840151949093019390935250919050565b6020815260006130636020830184613887565b600581106138335761383361380d565b61391e8188613904565b85602082015284604082015260c06060820152600061394060c083018661385b565b60808301949094525060a00152949350505050565b61395f8189613823565b86602082015260018060a01b038616604082015284606082015283608082015260e060a0820152600061399560e083018561385b565b90508260c083015298975050505050505050565b600080600080600080600060c0888a0312156139c457600080fd5b873596506020880135955060408801356139dd81613559565b945060608801359350608088013567ffffffffffffffff811115613a0057600080fd5b613a0c8a828b016134c4565b989b979a5095989497959660a090950135949350505050565b60008060008060008060808789031215613a3e57600080fd5b8635955060208701359450604087013567ffffffffffffffff80821115613a6457600080fd5b613a708a838b016134c4565b90965094506060890135915080821115613a8957600080fd5b50613a9689828a016134c4565b979a9699509497509295939492505050565b613ab3828251613904565b60208101516020830152604081015160408301526000606082015160c06060850152613ae260c085018261385b565b90506080830151608085015260a083015160a08501528091505092915050565b604081526000613b156040830185613aa8565b82810360208401526131958185613887565b6020815260006130636020830184613aa8565b600060208284031215613b4c57600080fd5b815161306381613792565b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b6020808252600b908201526a125b9d985b1a590818da5960aa1b604082015260600190565b600181811c90821680613bbf57607f821691505b602082108103613bdf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610edf57600081815260208120601f850160051c81016020861015613c0c5750805b601f850160051c820191505b8181101561174d57828155600101613c18565b67ffffffffffffffff831115613c4357613c436136b8565b613c5783613c518354613bab565b83613be5565b6000601f841160018114613c8b5760008515613c735750838201355b600019600387901b1c1916600186901b178355613ce5565b600083815260209020601f19861690835b82811015613cbc5786850135825560209485019460019092019101613c9c565b5086821015613cd95760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000613d29602083018486613cec565b949350505050565b815167ffffffffffffffff811115613d4b57613d4b6136b8565b613d5f81613d598454613bab565b84613be5565b602080601f831160018114613d945760008415613d7c5750858301515b600019600386901b1c1916600185901b17855561174d565b600085815260208120601f198616915b82811015613dc357888601518255948401946001909101908401613da4565b5085821015613de15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b600060018201613e1957613e19613df1565b5060010190565b60006101008b83528a6020840152806040840152613e418184018a8c613cec565b915050613e516060830188613823565b6001600160a01b0395909516608082015260a081019390935260c083019190915260e09091015295945050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b808202811582820484141761081a5761081a613df1565b600082613f4d57634e487b7160e01b600052601260045260246000fd5b500490565b87815286602082015260c060408201526000613f7260c083018789613cec565b6001600160a01b0395909516606083015250608081019290925260a090910152949350505050565b858152846020820152836040820152608060608201526000613fc0608083018486613cec565b979650505050505050565b600060208284031215613fdd57600080fd5b5051919050565b600060208284031215613ff657600080fd5b815161306381613559565b6d18dc99585d19541c9bdc1bdcd85b60921b815284600e820152603b60f81b602e82015283602f8201528183604f83013760009101604f019081529392505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6c6372656174655365727669636560981b815284600d820152603b60f81b602d82015283602e8201528183604e83013760009101604e019081529392505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614107816017850160208801613837565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351614138816028840160208801613837565b01602801949350505050565b602081526000613063602083018461385b565b8082018082111561081a5761081a613df1565b634e487b7160e01b600052603260045260246000fd5b60008161418f5761418f613df1565b506000190190565b600082516141a9818460208701613837565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220810e0f3326770d5cbf2063fa706b979e196534c448759006348f0d89ef76705a64736f6c63430008110033", + "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6080516144b7620001206000396000818161102e0152818161106e015281816113250152818161136501526113f401526144b76000f3fe6080604052600436106102305760003560e01c8063715018a61161012e578063c22c4f43116100ab578063ef0e239b1161006f578063ef0e239b1461072e578063f2fde38b1461075b578063f6c53d9b1461077b578063f9eaee0d14610792578063ff420375146107cc57600080fd5b8063c22c4f431461064a578063c2cfee271461067e578063ccaa7d2a146106b2578063d4eee1fc146106e0578063d547741f1461070e57600080fd5b8063a217fddf116100f2578063a217fddf146105b5578063a24bd889146105ca578063a7d5eaea146105dd578063aba21009146105fd578063b5735c1e1461062a57600080fd5b8063715018a6146104f057806371da85f9146105055780637c5a72cd146105575780638da5cb5b1461057757806391d148541461059557600080fd5b80632f2ff15d116101bc578063485cc95511610180578063485cc9551461043b5780634f1ef2861461045b57806352d1902d1461046e578063572b6c05146104835780636ce76f30146104bc57600080fd5b80632f2ff15d1461039b57806336568abe146103bb5780633659cfe6146103db5780633751d89c146103fb5780633ca2ad6f1461041b57600080fd5b8063156b39aa11610203578063156b39aa146102e55780631db087ff1461030a578063248a9ca31461033857806326d00668146103685780632afaf2201461038857600080fd5b806301ffc9a714610235578063089b7c731461026a5780631499f9e61461028c578063154664ed146102c5575b600080fd5b34801561024157600080fd5b5061025561025036600461368b565b6107ec565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061028a6102853660046136b5565b610823565b005b34801561029857600080fd5b50610130546102ad906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b3480156102d157600080fd5b5061028a6102e0366004613719565b6109c6565b3480156102f157600080fd5b506102fc6101365481565b604051908152602001610261565b34801561031657600080fd5b506102fc610325366004613789565b6101336020526000908152604090205481565b34801561034457600080fd5b506102fc610353366004613789565b600090815260fc602052604090206001015490565b34801561037457600080fd5b5061028a6103833660046137b7565b610cde565b6102fc6103963660046137d4565b610d41565b3480156103a757600080fd5b5061028a6103b6366004613874565b610f6c565b3480156103c757600080fd5b5061028a6103d6366004613874565b610f96565b3480156103e757600080fd5b5061028a6103f63660046137b7565b611024565b34801561040757600080fd5b5061028a6104163660046137b7565b611103565b34801561042757600080fd5b5061028a610436366004613789565b61115c565b34801561044757600080fd5b5061028a6104563660046138a4565b6111a4565b61028a6104693660046138e8565b61131b565b34801561047a57600080fd5b506102fc6113e7565b34801561048f57600080fd5b5061025561049e3660046137b7565b6001600160a01b031660009081526065602052604090205460ff1690565b3480156104c857600080fd5b506102fc7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f81565b3480156104fc57600080fd5b5061028a61149a565b34801561051157600080fd5b506105406105203660046137b7565b610135602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610261565b34801561056357600080fd5b5061028a6105723660046139ba565b6114ae565b34801561058357600080fd5b506033546001600160a01b03166102ad565b3480156105a157600080fd5b506102556105b0366004613874565b611583565b3480156105c157600080fd5b506102fc600081565b61028a6105d83660046139fb565b6115ae565b3480156105e957600080fd5b5061028a6105f8366004613aa8565b6118c8565b34801561060957600080fd5b5061061d6106183660046136b5565b61194a565b6040516102619190613bc6565b34801561063657600080fd5b5061028a6106453660046136b5565b611a87565b34801561065657600080fd5b5061066a610665366004613789565b611b2c565b604051610261989796959493929190613be9565b34801561068a57600080fd5b5061069e6106993660046136b5565b611c09565b604051610261989796959493929190613c47565b3480156106be57600080fd5b506102fc6106cd366004613789565b6101346020526000908152604090205481565b3480156106ec57600080fd5b506107006106fb3660046136b5565b611cf0565b604051610261929190613d18565b34801561071a57600080fd5b5061028a610729366004613874565b611f66565b34801561073a57600080fd5b5061074e610749366004613789565b611f8b565b6040516102619190613d3d565b34801561076757600080fd5b5061028a6107763660046137b7565b61210b565b34801561078757600080fd5b506102fc61012e5481565b34801561079e57600080fd5b506102556107ad3660046137b7565b6001600160a01b03166000908152610135602052604090205460ff1690565b3480156107d857600080fd5b5061028a6107e7366004613d50565b612181565b60006001600160e01b03198216637965db0b60e01b148061081d57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61012f5482906001600160a01b0316632fa117e5826108406123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561088a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ae9190613db1565b6108d35760405162461bcd60e51b81526004016108ca90613dce565b60405180910390fd5b600082815261013160205260409020600181015484146109255760405162461bcd60e51b815260206004820152600d60248201526c3737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff16600481111561093d5761093d613ad4565b146109825760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b805460ff191660031781556040518381527f853aa4be1ac86f37acfc91d42b57f1fe895205aa6f8f9b7caa77ca257049ab1a9060200160405180910390a150505050565b61012f5487906001600160a01b0316632fa117e5826109e36123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a519190613db1565b610a6d5760405162461bcd60e51b81526004016108ca90613dce565b60008781526101316020908152604080832061013283528184208c855290925282209091825460ff166004811115610aa757610aa7613ad4565b14610ae95760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b89816001015414610b2c5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b602e8614610b4c5760405162461bcd60e51b81526004016108ca90613dfd565b6001815460ff166001811115610b6457610b64613ad4565b03610ba55760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481d985b1a59185d1959607a1b60448201526064016108ca565b60068201546001600160a01b031660009081526101356020526040902060010154881015610c065760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b8315610c695761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015610c5057600080fd5b505afa158015610c64573d6000803e3d6000fd5b505050505b6003810188905560058101610c7f878983613ea2565b5060068101859055600781018490556040517ffbfaa6f4e508bec40137ac265a7424e16a2d209355b2f4a35de5a80ba8fec1db90610cca908b908d908b908b908e908c908c90613f8c565b60405180910390a150505050505050505050565b610ce66123b8565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b61012f5460009089906001600160a01b0316632fa117e582610d616123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610dab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcf9190613db1565b610deb5760405162461bcd60e51b81526004016108ca90613dce565b610dfa8a8a8a8a8a8a8a612431565b61012e80549081906000610e0d83613fe1565b9091555050600081815261013160205260409020805460ff19168155600181018c905560038101610e3f8a8c83613ea2565b50600581018b90556006810180546001600160a01b0319166001600160a01b0388161790556007810185905560008c81526101336020526040902054158015610e95575060008c81526101346020526040902054155b15610efa5761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015610ee157600080fd5b505af1158015610ef5573d6000803e3d6000fd5b505050505b60008c815261013360205260408120805491610f1583613fe1565b91905055507fe7f6435fc92b0ccd6f56395ae67b06f2cdb9680c0179f87f5821431304ad3f3e828d8d8d8d8b8b604051610f559796959493929190613ffa565b60405180910390a1509a9950505050505050505050565b600082815260fc6020526040902060010154610f878161263a565b610f91838361264b565b505050565b610f9e6123a9565b6001600160a01b0316816001600160a01b0316146110165760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108ca565b61102082826126d2565b5050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361106c5760405162461bcd60e51b81526004016108ca9061403f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166110b560008051602061443b833981519152546001600160a01b031690565b6001600160a01b0316146110db5760405162461bcd60e51b81526004016108ca9061408b565b6110e481612757565b604080516000808252602082019092526111009183919061275f565b50565b61110b6123b8565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee69101610d36565b60006111678161263a565b6101368290556040518281527f577d7afcf67637a2f602cba220bbb292c1d715380dd011bfec748c3f641b2fd29060200160405180910390a15050565b600054610100900460ff16158080156111c45750600054600160ff909116105b806111de5750303b1580156111de575060005460ff166001145b6112415760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108ca565b6000805460ff191660011790558015611264576000805461ff0019166101001790555b61126c6128ca565b6112746128f9565b61127c6128f9565b61128e60006112896123a9565b612920565b61012f80546001600160a01b038086166001600160a01b031992831617909255610130805492851692909116919091179055600161012e556112d0601e61115c565b8015610f91576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036113635760405162461bcd60e51b81526004016108ca9061403f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166113ac60008051602061443b833981519152546001600160a01b031690565b6001600160a01b0316146113d25760405162461bcd60e51b81526004016108ca9061408b565b6113db82612757565b6110208282600161275f565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146114875760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108ca565b5060008051602061443b83398151915290565b6114a26123b8565b6114ac600061292a565b565b6114b66123b8565b6001600160a01b0383161580156114cb575081155b156115185760405162461bcd60e51b815260206004820152601d60248201527f4f776e65722063616e27742072656d6f7665204f78206164647265737300000060448201526064016108ca565b6001600160a01b03831660008181526101356020908152604091829020805460ff19168615159081178255600190910185905582519384529083015281018290527f42b585a1da1cff4b571e7a78aea1b4601b1d128de41a0feebd8a77aaf48b9d889060600161130e565b600091825260fc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61012f548a906001600160a01b0316632fa117e5826115cb6123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611615573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116399190613db1565b6116555760405162461bcd60e51b81526004016108ca90613dce565b60008a8152610131602052604090206116758c8c8c8c8c8c8b8b8b61297c565b60408051610100810182526000815260208082018f905260068401546001600160a01b031682840152606082018d9052608082018c90528251601f8b01829004820281018201909352898352909160a08301918b908b9081908401838280828437600081840152601f19601f8201169050808301925050505050505081526020018781526020018481525061013260008d815260200190815260200160002060008e815260200190815260200160002060008201518160000160006101000a81548160ff0219169083600181111561174f5761174f613ad4565b02179055506020820151600182015560408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a082015160058201906117ac90826140d7565b5060c0820151600682015560e09091015160079091015560008c815261013360205260409020541580156117ed575060008c81526101346020526040902054155b156118525761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b15801561183957600080fd5b505af115801561184d573d6000803e3d6000fd5b505050505b60008c81526101346020526040812080549161186d83613fe1565b91905055507fabd26455c3256ad90125661f4c1a4c16fecf585ccade21e749c56d8fd44bb1dd8b8d8a8a60008f8f8d8b6040516118b299989796959493929190614197565b60405180910390a1505050505050505050505050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f6118f28161263a565b60008481526101316020908152604080832061013283528184208785529092529091208154600160ff1991821681178455808301546002850155600484018690558254909183911682805b0217905550505050505050565b6119526135ed565b60008381526101326020908152604080832085845290915290819020815161010081019092528054829060ff16600181111561199057611990613ad4565b60018111156119a1576119a1613ad4565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a0909201916119e990613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611a1590613e22565b8015611a625780601f10611a3757610100808354040283529160200191611a62565b820191906000526020600020905b815481529060010190602001808311611a4557829003601f168201915b5050505050815260200160068201548152602001600782015481525050905092915050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611ab18161263a565b6000838152610131602090815260408083206101328352818420600282015485529092528220600381015491929091611aeb8660646141ee565b611af59190614205565b9050610136548110611b1157825460ff19166002178355611b24565b8254600490849060ff191660018361193d565b505050505050565b61013160205260009081526040902080546001820154600283015460038401805460ff909416949293919291611b6190613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611b8d90613e22565b8015611bda5780601f10611baf57610100808354040283529160200191611bda565b820191906000526020600020905b815481529060010190602001808311611bbd57829003601f168201915b505050600484015460058501546006860154600790960154949591949093506001600160a01b03909116915088565b61013260209081526000928352604080842090915290825290208054600182015460028301546003840154600485015460058601805460ff9096169694956001600160a01b03909416949293919291611c6190613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611c8d90613e22565b8015611cda5780601f10611caf57610100808354040283529160200191611cda565b820191906000526020600020905b815481529060010190602001808311611cbd57829003601f168201915b5050505050908060060154908060070154905088565b611cf861363c565b611d006135ed565b60008481526101316020526040808220815161010081019092528054829060ff166004811115611d3257611d32613ad4565b6004811115611d4357611d43613ad4565b81526020016001820154815260200160028201548152602001600382018054611d6b90613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611d9790613e22565b8015611de45780601f10611db957610100808354040283529160200191611de4565b820191906000526020600020905b815481529060010190602001808311611dc757829003601f168201915b50505091835250506004820154602080830191909152600583015460408084019190915260068401546001600160a01b03166060840152600790930154608090920191909152600088815261013282528281208882529091528181208251610100810190935280549394509092829060ff166001811115611e6757611e67613ad4565b6001811115611e7857611e78613ad4565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611ec090613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611eec90613e22565b8015611f395780601f10611f0e57610100808354040283529160200191611f39565b820191906000526020600020905b815481529060010190602001808311611f1c57829003601f168201915b505050918352505060068201546020820152600790910154604090910152919350909150505b9250929050565b600082815260fc6020526040902060010154611f818161263a565b610f9183836126d2565b611f9361363c565b61012e548210611fe55760405162461bcd60e51b815260206004820152601a60248201527f54686973207365727669636520646f65736e277420657869737400000000000060448201526064016108ca565b6000828152610131602052604090819020815161010081019092528054829060ff16600481111561201857612018613ad4565b600481111561202957612029613ad4565b8152602001600182015481526020016002820154815260200160038201805461205190613e22565b80601f016020809104026020016040519081016040528092919081815260200182805461207d90613e22565b80156120ca5780601f1061209f576101008083540402835291602001916120ca565b820191906000526020600020905b8154815290600101906020018083116120ad57829003601f168201915b5050509183525050600482015460208201526005820154604082015260068201546001600160a01b0316606082015260079091015460809091015292915050565b6121136123b8565b6001600160a01b0381166121785760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108ca565b6111008161292a565b61012f5485906001600160a01b0316632fa117e58261219e6123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156121e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220c9190613db1565b6122285760405162461bcd60e51b81526004016108ca90613dce565b6000858152610131602052604090206001810154871461227a5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff16600481111561229257612292613ad4565b146122d75760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b602e83146122f75760405162461bcd60e51b81526004016108ca90613dfd565b806007015485101561234b5760405162461bcd60e51b815260206004820152601c60248201527f43616e27742072656475636520726566657272616c20616d6f756e740000000060448201526064016108ca565b6003810161235a848683613ea2565b50600781018590556040517fae55ce3c351e2400a1a143e7ed66668e581e1656ad1797a317e415d03588091690612398908890879087908a90614227565b60405180910390a150505050505050565b60006123b3612dc9565b905090565b6123c06123a9565b6001600160a01b03166123db6033546001600160a01b031690565b6001600160a01b0316146114ac5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108ca565b61013054604051638a98636360e01b8152600481018890526000916001600160a01b031690638a98636390602401602060405180830381865afa15801561247c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a09190614252565b90508034146124e65760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b602e85146125065760405162461bcd60e51b81526004016108ca90613dfd565b6001600160a01b0382166000908152610135602052604090205460ff166125635760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108ca565b61013054604051631fff7f2760e11b8152600481018990526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa1580156125ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d2919061426b565b90506001600160a01b0381161561262f57600089815261013360209081526040808320549051612609928d92918c918c9101614288565b60405160208183030381529060405280519060200120905061262d86868385612e02565b505b505050505050505050565b611100816126466123a9565b612ef6565b6126558282611583565b61102057600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561268e6123a9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6126dc8282611583565b1561102057600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191690556127136123a9565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6111006123b8565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561279257610f9183612f4f565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156127ec575060408051601f3d908101601f191682019092526127e991810190614252565b60015b61284f5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108ca565b60008051602061443b83398151915281146128be5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108ca565b50610f91838383612feb565b600054610100900460ff166128f15760405162461bcd60e51b81526004016108ca906142c9565b6114ac613016565b600054610100900460ff166114ac5760405162461bcd60e51b81526004016108ca906142c9565b611020828261264b565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61013054604051634a7ab1d560e01b8152600481018890526000916001600160a01b031690634a7ab1d590602401602060405180830381865afa1580156129c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129eb9190614252565b9050803414612a315760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b60008981526101316020908152604080832060068101546001600160a01b03168452610135909252909120600101546007820154612a6f908b614314565b1015612aae5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b6000815460ff166004811115612ac657612ac6613ad4565b14612b085760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b8060010154600003612b505760405162461bcd60e51b815260206004820152601160248201527014d95c9d9a58d9481b9bdd08195e1a5cdd607a1b60448201526064016108ca565b60008a8152610132602090815260408083208e84529091529020600101548b9003612bb65760405162461bcd60e51b81526020600482015260166024820152751c1c9bdc1bdcd85b08185b1c9958591e48195e1a5cdd60521b60448201526064016108ca565b8215612c1c576000816007015411612c1c5760405162461bcd60e51b8152602060048201526024808201527f43616e277420726566657220736f6d656f6e6520666f722074686973207365726044820152637669636560e01b60648201526084016108ca565b8a816001015403612c795760405162461bcd60e51b815260206004820152602160248201527f63616e27742063726561746520666f7220796f7572206f776e207365727669636044820152606560f81b60648201526084016108ca565b602e8614612c995760405162461bcd60e51b81526004016108ca90613dfd565b61013054604051631fff7f2760e11b8152600481018a90526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d08919061426b565b90506001600160a01b03811615612d585760008c8c8a8a604051602001612d329493929190614327565b604051602081830303815290604052805190602001209050612d5687878385612e02565b505b8315612dbb5761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015612da257600080fd5b505afa158015612db6573d6000803e3d6000fd5b505050505b505050505050505050505050565b600060143610801590612deb57503360009081526065602052604090205460ff165b15612dfd575060131936013560601c90565b503390565b6000612e5b836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000612e9f8287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061304d92505050565b9050806001600160a01b0316836001600160a01b031614611b245760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064016108ca565b612f008282611583565b61102057612f0d81613071565b612f18836020613083565b604051602001612f29929190614369565b60408051601f198184030181529082905262461bcd60e51b82526108ca916004016143de565b6001600160a01b0381163b612fbc5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108ca565b60008051602061443b83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b612ff483613226565b6000825111806130015750805b15610f91576130108383613266565b50505050565b600054610100900460ff1661303d5760405162461bcd60e51b81526004016108ca906142c9565b6114ac6130486123a9565b61292a565b600080600061305c858561335a565b915091506130698161339c565b509392505050565b606061081d6001600160a01b03831660145b606060006130928360026141ee565b61309d906002614314565b67ffffffffffffffff8111156130b5576130b56138d2565b6040519080825280601f01601f1916602001820160405280156130df576020820181803683370190505b509050600360fc1b816000815181106130fa576130fa6143f1565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613129576131296143f1565b60200101906001600160f81b031916908160001a905350600061314d8460026141ee565b613158906001614314565b90505b60018111156131d0576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061318c5761318c6143f1565b1a60f81b8282815181106131a2576131a26143f1565b60200101906001600160f81b031916908160001a90535060049490941c936131c981614407565b905061315b565b50831561321f5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108ca565b9392505050565b61322f81612f4f565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6132ce5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108ca565b600080846001600160a01b0316846040516132e9919061441e565b600060405180830381855af49150503d8060008114613324576040519150601f19603f3d011682016040523d82523d6000602084013e613329565b606091505b5091509150613351828260405180606001604052806027815260200161445b602791396134e6565b95945050505050565b60008082516041036133905760208301516040840151606085015160001a613384878285856134ff565b94509450505050611f5f565b50600090506002611f5f565b60008160048111156133b0576133b0613ad4565b036133b85750565b60018160048111156133cc576133cc613ad4565b036134195760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108ca565b600281600481111561342d5761342d613ad4565b0361347a5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108ca565b600381600481111561348e5761348e613ad4565b036111005760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108ca565b606083156134f557508161321f565b61321f83836135c3565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561353657506000905060036135ba565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561358a573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166135b3576000600192509250506135ba565b9150600090505b94509492505050565b8151156135d35781518083602001fd5b8060405162461bcd60e51b81526004016108ca91906143de565b60408051610100810190915280600081526020016000815260200160006001600160a01b0316815260200160008152602001600081526020016060815260200160008152602001600081525090565b6040805161010081019091528060008152602001600081526020016000815260200160608152602001600081526020016000815260200160006001600160a01b03168152602001600081525090565b60006020828403121561369d57600080fd5b81356001600160e01b03198116811461321f57600080fd5b600080604083850312156136c857600080fd5b50508035926020909101359150565b60008083601f8401126136e957600080fd5b50813567ffffffffffffffff81111561370157600080fd5b602083019150836020828501011115611f5f57600080fd5b600080600080600080600060c0888a03121561373457600080fd5b873596506020880135955060408801359450606088013567ffffffffffffffff81111561376057600080fd5b61376c8a828b016136d7565b989b979a50959895979660808701359660a0013595509350505050565b60006020828403121561379b57600080fd5b5035919050565b6001600160a01b038116811461110057600080fd5b6000602082840312156137c957600080fd5b813561321f816137a2565b60008060008060008060008060c0898b0312156137f057600080fd5b8835975060208901359650604089013567ffffffffffffffff8082111561381657600080fd5b6138228c838d016136d7565b909850965060608b013591508082111561383b57600080fd5b506138488b828c016136d7565b909550935050608089013561385c816137a2565b8092505060a089013590509295985092959890939650565b6000806040838503121561388757600080fd5b823591506020830135613899816137a2565b809150509250929050565b600080604083850312156138b757600080fd5b82356138c2816137a2565b91506020830135613899816137a2565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156138fb57600080fd5b8235613906816137a2565b9150602083013567ffffffffffffffff8082111561392357600080fd5b818501915085601f83011261393757600080fd5b813581811115613949576139496138d2565b604051601f8201601f19908116603f01168101908382118183101715613971576139716138d2565b8160405282815288602084870101111561398a57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b801515811461110057600080fd5b6000806000606084860312156139cf57600080fd5b83356139da816137a2565b925060208401356139ea816139ac565b929592945050506040919091013590565b6000806000806000806000806000806101008b8d031215613a1b57600080fd5b8a35995060208b0135985060408b0135975060608b0135965060808b013567ffffffffffffffff80821115613a4f57600080fd5b613a5b8e838f016136d7565b909850965060a08d0135955060c08d0135915080821115613a7b57600080fd5b50613a888d828e016136d7565b9150809450508092505060e08b013590509295989b9194979a5092959850565b600080600060608486031215613abd57600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052602160045260246000fd5b60028110613afa57613afa613ad4565b9052565b60005b83811015613b19578181015183820152602001613b01565b50506000910152565b60008151808452613b3a816020860160208601613afe565b601f01601f19169290920160200192915050565b6000610100613b5e848451613aea565b6020830151602085015260018060a01b036040840151166040850152606083015160608501526080830151608085015260a08301518160a0860152613ba582860182613b22565b91505060c083015160c085015260e083015160e08501528091505092915050565b60208152600061321f6020830184613b4e565b60058110613afa57613afa613ad4565b6000610100613bf8838c613bd9565b896020840152886040840152806060840152613c1681840189613b22565b6080840197909752505060a08101939093526001600160a01b039190911660c083015260e090910152949350505050565b6000610100613c56838c613aea565b89602084015260018060a01b03891660408401528760608401528660808401528060a0840152613c8881840187613b22565b60c0840195909552505060e001529695505050505050565b6000610100613cb0848451613bd9565b60208301516020850152604083015160408501526060830151816060860152613cdb82860182613b22565b6080858101519087015260a0808601519087015260c0808601516001600160a01b03169087015260e0948501519490950193909352509192915050565b604081526000613d2b6040830185613ca0565b82810360208401526133518185613b4e565b60208152600061321f6020830184613ca0565b600080600080600060808688031215613d6857600080fd5b853594506020860135935060408601359250606086013567ffffffffffffffff811115613d9457600080fd5b613da0888289016136d7565b969995985093965092949392505050565b600060208284031215613dc357600080fd5b815161321f816139ac565b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b6020808252600b908201526a125b9d985b1a590818da5960aa1b604082015260600190565b600181811c90821680613e3657607f821691505b602082108103613e5657634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610f9157600081815260208120601f850160051c81016020861015613e835750805b601f850160051c820191505b81811015611b2457828155600101613e8f565b67ffffffffffffffff831115613eba57613eba6138d2565b613ece83613ec88354613e22565b83613e5c565b6000601f841160018114613f025760008515613eea5750838201355b600019600387901b1c1916600186901b178355613f5c565b600083815260209020601f19861690835b82811015613f335786850135825560209485019460019092019101613f13565b5086821015613f505760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b87815286602082015260c060408201526000613fac60c083018789613f63565b606083019590955250608081019290925260a090910152949350505050565b634e487b7160e01b600052601160045260246000fd5b600060018201613ff357613ff3613fcb565b5060010190565b87815286602082015285604082015260c06060820152600061402060c083018688613f63565b6001600160a01b039490941660808301525060a0015295945050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b815167ffffffffffffffff8111156140f1576140f16138d2565b614105816140ff8454613e22565b84613e5c565b602080601f83116001811461413a57600084156141225750858301515b600019600386901b1c1916600185901b178555611b24565b600085815260208120601f198616915b828110156141695788860151825594840194600190910190840161414a565b50858210156141875787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006101008b83528a60208401528060408401526141b88184018a8c613f63565b9150506141c86060830188613aea565b8560808301528460a08301528360c08301528260e08301529a9950505050505050505050565b808202811582820484141761081d5761081d613fcb565b60008261422257634e487b7160e01b600052601260045260246000fd5b500490565b848152606060208201526000614241606083018587613f63565b905082604083015295945050505050565b60006020828403121561426457600080fd5b5051919050565b60006020828403121561427d57600080fd5b815161321f816137a2565b6c6372656174655365727669636560981b815284600d820152603b60f81b602d82015283602e8201528183604e83013760009101604e019081529392505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8082018082111561081d5761081d613fcb565b6d18dc99585d19541c9bdc1bdcd85b60921b815284600e820152603b60f81b602e82015283602f8201528183604f83013760009101604f019081529392505050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516143a1816017850160208801613afe565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516143d2816028840160208801613afe565b01602801949350505050565b60208152600061321f6020830184613b22565b634e487b7160e01b600052603260045260246000fd5b60008161441657614416613fcb565b506000190190565b60008251614430818460208701613afe565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220397b6e8ab583d064618d0d5b7fe3da4cfb56beab325a99d1a0fca57da22eb57e64736f6c63430008110033", + "deployedBytecode": "0x6080604052600436106102305760003560e01c8063715018a61161012e578063c22c4f43116100ab578063ef0e239b1161006f578063ef0e239b1461072e578063f2fde38b1461075b578063f6c53d9b1461077b578063f9eaee0d14610792578063ff420375146107cc57600080fd5b8063c22c4f431461064a578063c2cfee271461067e578063ccaa7d2a146106b2578063d4eee1fc146106e0578063d547741f1461070e57600080fd5b8063a217fddf116100f2578063a217fddf146105b5578063a24bd889146105ca578063a7d5eaea146105dd578063aba21009146105fd578063b5735c1e1461062a57600080fd5b8063715018a6146104f057806371da85f9146105055780637c5a72cd146105575780638da5cb5b1461057757806391d148541461059557600080fd5b80632f2ff15d116101bc578063485cc95511610180578063485cc9551461043b5780634f1ef2861461045b57806352d1902d1461046e578063572b6c05146104835780636ce76f30146104bc57600080fd5b80632f2ff15d1461039b57806336568abe146103bb5780633659cfe6146103db5780633751d89c146103fb5780633ca2ad6f1461041b57600080fd5b8063156b39aa11610203578063156b39aa146102e55780631db087ff1461030a578063248a9ca31461033857806326d00668146103685780632afaf2201461038857600080fd5b806301ffc9a714610235578063089b7c731461026a5780631499f9e61461028c578063154664ed146102c5575b600080fd5b34801561024157600080fd5b5061025561025036600461368b565b6107ec565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061028a6102853660046136b5565b610823565b005b34801561029857600080fd5b50610130546102ad906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b3480156102d157600080fd5b5061028a6102e0366004613719565b6109c6565b3480156102f157600080fd5b506102fc6101365481565b604051908152602001610261565b34801561031657600080fd5b506102fc610325366004613789565b6101336020526000908152604090205481565b34801561034457600080fd5b506102fc610353366004613789565b600090815260fc602052604090206001015490565b34801561037457600080fd5b5061028a6103833660046137b7565b610cde565b6102fc6103963660046137d4565b610d41565b3480156103a757600080fd5b5061028a6103b6366004613874565b610f6c565b3480156103c757600080fd5b5061028a6103d6366004613874565b610f96565b3480156103e757600080fd5b5061028a6103f63660046137b7565b611024565b34801561040757600080fd5b5061028a6104163660046137b7565b611103565b34801561042757600080fd5b5061028a610436366004613789565b61115c565b34801561044757600080fd5b5061028a6104563660046138a4565b6111a4565b61028a6104693660046138e8565b61131b565b34801561047a57600080fd5b506102fc6113e7565b34801561048f57600080fd5b5061025561049e3660046137b7565b6001600160a01b031660009081526065602052604090205460ff1690565b3480156104c857600080fd5b506102fc7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f81565b3480156104fc57600080fd5b5061028a61149a565b34801561051157600080fd5b506105406105203660046137b7565b610135602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610261565b34801561056357600080fd5b5061028a6105723660046139ba565b6114ae565b34801561058357600080fd5b506033546001600160a01b03166102ad565b3480156105a157600080fd5b506102556105b0366004613874565b611583565b3480156105c157600080fd5b506102fc600081565b61028a6105d83660046139fb565b6115ae565b3480156105e957600080fd5b5061028a6105f8366004613aa8565b6118c8565b34801561060957600080fd5b5061061d6106183660046136b5565b61194a565b6040516102619190613bc6565b34801561063657600080fd5b5061028a6106453660046136b5565b611a87565b34801561065657600080fd5b5061066a610665366004613789565b611b2c565b604051610261989796959493929190613be9565b34801561068a57600080fd5b5061069e6106993660046136b5565b611c09565b604051610261989796959493929190613c47565b3480156106be57600080fd5b506102fc6106cd366004613789565b6101346020526000908152604090205481565b3480156106ec57600080fd5b506107006106fb3660046136b5565b611cf0565b604051610261929190613d18565b34801561071a57600080fd5b5061028a610729366004613874565b611f66565b34801561073a57600080fd5b5061074e610749366004613789565b611f8b565b6040516102619190613d3d565b34801561076757600080fd5b5061028a6107763660046137b7565b61210b565b34801561078757600080fd5b506102fc61012e5481565b34801561079e57600080fd5b506102556107ad3660046137b7565b6001600160a01b03166000908152610135602052604090205460ff1690565b3480156107d857600080fd5b5061028a6107e7366004613d50565b612181565b60006001600160e01b03198216637965db0b60e01b148061081d57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61012f5482906001600160a01b0316632fa117e5826108406123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561088a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ae9190613db1565b6108d35760405162461bcd60e51b81526004016108ca90613dce565b60405180910390fd5b600082815261013160205260409020600181015484146109255760405162461bcd60e51b815260206004820152600d60248201526c3737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff16600481111561093d5761093d613ad4565b146109825760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b805460ff191660031781556040518381527f853aa4be1ac86f37acfc91d42b57f1fe895205aa6f8f9b7caa77ca257049ab1a9060200160405180910390a150505050565b61012f5487906001600160a01b0316632fa117e5826109e36123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a519190613db1565b610a6d5760405162461bcd60e51b81526004016108ca90613dce565b60008781526101316020908152604080832061013283528184208c855290925282209091825460ff166004811115610aa757610aa7613ad4565b14610ae95760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b89816001015414610b2c5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b602e8614610b4c5760405162461bcd60e51b81526004016108ca90613dfd565b6001815460ff166001811115610b6457610b64613ad4565b03610ba55760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481d985b1a59185d1959607a1b60448201526064016108ca565b60068201546001600160a01b031660009081526101356020526040902060010154881015610c065760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b8315610c695761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015610c5057600080fd5b505afa158015610c64573d6000803e3d6000fd5b505050505b6003810188905560058101610c7f878983613ea2565b5060068101859055600781018490556040517ffbfaa6f4e508bec40137ac265a7424e16a2d209355b2f4a35de5a80ba8fec1db90610cca908b908d908b908b908e908c908c90613f8c565b60405180910390a150505050505050505050565b610ce66123b8565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b61012f5460009089906001600160a01b0316632fa117e582610d616123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610dab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcf9190613db1565b610deb5760405162461bcd60e51b81526004016108ca90613dce565b610dfa8a8a8a8a8a8a8a612431565b61012e80549081906000610e0d83613fe1565b9091555050600081815261013160205260409020805460ff19168155600181018c905560038101610e3f8a8c83613ea2565b50600581018b90556006810180546001600160a01b0319166001600160a01b0388161790556007810185905560008c81526101336020526040902054158015610e95575060008c81526101346020526040902054155b15610efa5761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015610ee157600080fd5b505af1158015610ef5573d6000803e3d6000fd5b505050505b60008c815261013360205260408120805491610f1583613fe1565b91905055507fe7f6435fc92b0ccd6f56395ae67b06f2cdb9680c0179f87f5821431304ad3f3e828d8d8d8d8b8b604051610f559796959493929190613ffa565b60405180910390a1509a9950505050505050505050565b600082815260fc6020526040902060010154610f878161263a565b610f91838361264b565b505050565b610f9e6123a9565b6001600160a01b0316816001600160a01b0316146110165760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108ca565b61102082826126d2565b5050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361106c5760405162461bcd60e51b81526004016108ca9061403f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166110b560008051602061443b833981519152546001600160a01b031690565b6001600160a01b0316146110db5760405162461bcd60e51b81526004016108ca9061408b565b6110e481612757565b604080516000808252602082019092526111009183919061275f565b50565b61110b6123b8565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee69101610d36565b60006111678161263a565b6101368290556040518281527f577d7afcf67637a2f602cba220bbb292c1d715380dd011bfec748c3f641b2fd29060200160405180910390a15050565b600054610100900460ff16158080156111c45750600054600160ff909116105b806111de5750303b1580156111de575060005460ff166001145b6112415760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108ca565b6000805460ff191660011790558015611264576000805461ff0019166101001790555b61126c6128ca565b6112746128f9565b61127c6128f9565b61128e60006112896123a9565b612920565b61012f80546001600160a01b038086166001600160a01b031992831617909255610130805492851692909116919091179055600161012e556112d0601e61115c565b8015610f91576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036113635760405162461bcd60e51b81526004016108ca9061403f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166113ac60008051602061443b833981519152546001600160a01b031690565b6001600160a01b0316146113d25760405162461bcd60e51b81526004016108ca9061408b565b6113db82612757565b6110208282600161275f565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146114875760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108ca565b5060008051602061443b83398151915290565b6114a26123b8565b6114ac600061292a565b565b6114b66123b8565b6001600160a01b0383161580156114cb575081155b156115185760405162461bcd60e51b815260206004820152601d60248201527f4f776e65722063616e27742072656d6f7665204f78206164647265737300000060448201526064016108ca565b6001600160a01b03831660008181526101356020908152604091829020805460ff19168615159081178255600190910185905582519384529083015281018290527f42b585a1da1cff4b571e7a78aea1b4601b1d128de41a0feebd8a77aaf48b9d889060600161130e565b600091825260fc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61012f548a906001600160a01b0316632fa117e5826115cb6123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611615573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116399190613db1565b6116555760405162461bcd60e51b81526004016108ca90613dce565b60008a8152610131602052604090206116758c8c8c8c8c8c8b8b8b61297c565b60408051610100810182526000815260208082018f905260068401546001600160a01b031682840152606082018d9052608082018c90528251601f8b01829004820281018201909352898352909160a08301918b908b9081908401838280828437600081840152601f19601f8201169050808301925050505050505081526020018781526020018481525061013260008d815260200190815260200160002060008e815260200190815260200160002060008201518160000160006101000a81548160ff0219169083600181111561174f5761174f613ad4565b02179055506020820151600182015560408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a082015160058201906117ac90826140d7565b5060c0820151600682015560e09091015160079091015560008c815261013360205260409020541580156117ed575060008c81526101346020526040902054155b156118525761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b15801561183957600080fd5b505af115801561184d573d6000803e3d6000fd5b505050505b60008c81526101346020526040812080549161186d83613fe1565b91905055507fabd26455c3256ad90125661f4c1a4c16fecf585ccade21e749c56d8fd44bb1dd8b8d8a8a60008f8f8d8b6040516118b299989796959493929190614197565b60405180910390a1505050505050505050505050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f6118f28161263a565b60008481526101316020908152604080832061013283528184208785529092529091208154600160ff1991821681178455808301546002850155600484018690558254909183911682805b0217905550505050505050565b6119526135ed565b60008381526101326020908152604080832085845290915290819020815161010081019092528054829060ff16600181111561199057611990613ad4565b60018111156119a1576119a1613ad4565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a0909201916119e990613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611a1590613e22565b8015611a625780601f10611a3757610100808354040283529160200191611a62565b820191906000526020600020905b815481529060010190602001808311611a4557829003601f168201915b5050505050815260200160068201548152602001600782015481525050905092915050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611ab18161263a565b6000838152610131602090815260408083206101328352818420600282015485529092528220600381015491929091611aeb8660646141ee565b611af59190614205565b9050610136548110611b1157825460ff19166002178355611b24565b8254600490849060ff191660018361193d565b505050505050565b61013160205260009081526040902080546001820154600283015460038401805460ff909416949293919291611b6190613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611b8d90613e22565b8015611bda5780601f10611baf57610100808354040283529160200191611bda565b820191906000526020600020905b815481529060010190602001808311611bbd57829003601f168201915b505050600484015460058501546006860154600790960154949591949093506001600160a01b03909116915088565b61013260209081526000928352604080842090915290825290208054600182015460028301546003840154600485015460058601805460ff9096169694956001600160a01b03909416949293919291611c6190613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611c8d90613e22565b8015611cda5780601f10611caf57610100808354040283529160200191611cda565b820191906000526020600020905b815481529060010190602001808311611cbd57829003601f168201915b5050505050908060060154908060070154905088565b611cf861363c565b611d006135ed565b60008481526101316020526040808220815161010081019092528054829060ff166004811115611d3257611d32613ad4565b6004811115611d4357611d43613ad4565b81526020016001820154815260200160028201548152602001600382018054611d6b90613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611d9790613e22565b8015611de45780601f10611db957610100808354040283529160200191611de4565b820191906000526020600020905b815481529060010190602001808311611dc757829003601f168201915b50505091835250506004820154602080830191909152600583015460408084019190915260068401546001600160a01b03166060840152600790930154608090920191909152600088815261013282528281208882529091528181208251610100810190935280549394509092829060ff166001811115611e6757611e67613ad4565b6001811115611e7857611e78613ad4565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611ec090613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611eec90613e22565b8015611f395780601f10611f0e57610100808354040283529160200191611f39565b820191906000526020600020905b815481529060010190602001808311611f1c57829003601f168201915b505050918352505060068201546020820152600790910154604090910152919350909150505b9250929050565b600082815260fc6020526040902060010154611f818161263a565b610f9183836126d2565b611f9361363c565b61012e548210611fe55760405162461bcd60e51b815260206004820152601a60248201527f54686973207365727669636520646f65736e277420657869737400000000000060448201526064016108ca565b6000828152610131602052604090819020815161010081019092528054829060ff16600481111561201857612018613ad4565b600481111561202957612029613ad4565b8152602001600182015481526020016002820154815260200160038201805461205190613e22565b80601f016020809104026020016040519081016040528092919081815260200182805461207d90613e22565b80156120ca5780601f1061209f576101008083540402835291602001916120ca565b820191906000526020600020905b8154815290600101906020018083116120ad57829003601f168201915b5050509183525050600482015460208201526005820154604082015260068201546001600160a01b0316606082015260079091015460809091015292915050565b6121136123b8565b6001600160a01b0381166121785760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108ca565b6111008161292a565b61012f5485906001600160a01b0316632fa117e58261219e6123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156121e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220c9190613db1565b6122285760405162461bcd60e51b81526004016108ca90613dce565b6000858152610131602052604090206001810154871461227a5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff16600481111561229257612292613ad4565b146122d75760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b602e83146122f75760405162461bcd60e51b81526004016108ca90613dfd565b806007015485101561234b5760405162461bcd60e51b815260206004820152601c60248201527f43616e27742072656475636520726566657272616c20616d6f756e740000000060448201526064016108ca565b6003810161235a848683613ea2565b50600781018590556040517fae55ce3c351e2400a1a143e7ed66668e581e1656ad1797a317e415d03588091690612398908890879087908a90614227565b60405180910390a150505050505050565b60006123b3612dc9565b905090565b6123c06123a9565b6001600160a01b03166123db6033546001600160a01b031690565b6001600160a01b0316146114ac5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108ca565b61013054604051638a98636360e01b8152600481018890526000916001600160a01b031690638a98636390602401602060405180830381865afa15801561247c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a09190614252565b90508034146124e65760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b602e85146125065760405162461bcd60e51b81526004016108ca90613dfd565b6001600160a01b0382166000908152610135602052604090205460ff166125635760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108ca565b61013054604051631fff7f2760e11b8152600481018990526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa1580156125ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d2919061426b565b90506001600160a01b0381161561262f57600089815261013360209081526040808320549051612609928d92918c918c9101614288565b60405160208183030381529060405280519060200120905061262d86868385612e02565b505b505050505050505050565b611100816126466123a9565b612ef6565b6126558282611583565b61102057600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561268e6123a9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6126dc8282611583565b1561102057600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191690556127136123a9565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6111006123b8565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561279257610f9183612f4f565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156127ec575060408051601f3d908101601f191682019092526127e991810190614252565b60015b61284f5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108ca565b60008051602061443b83398151915281146128be5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108ca565b50610f91838383612feb565b600054610100900460ff166128f15760405162461bcd60e51b81526004016108ca906142c9565b6114ac613016565b600054610100900460ff166114ac5760405162461bcd60e51b81526004016108ca906142c9565b611020828261264b565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61013054604051634a7ab1d560e01b8152600481018890526000916001600160a01b031690634a7ab1d590602401602060405180830381865afa1580156129c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129eb9190614252565b9050803414612a315760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b60008981526101316020908152604080832060068101546001600160a01b03168452610135909252909120600101546007820154612a6f908b614314565b1015612aae5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b6000815460ff166004811115612ac657612ac6613ad4565b14612b085760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b8060010154600003612b505760405162461bcd60e51b815260206004820152601160248201527014d95c9d9a58d9481b9bdd08195e1a5cdd607a1b60448201526064016108ca565b60008a8152610132602090815260408083208e84529091529020600101548b9003612bb65760405162461bcd60e51b81526020600482015260166024820152751c1c9bdc1bdcd85b08185b1c9958591e48195e1a5cdd60521b60448201526064016108ca565b8215612c1c576000816007015411612c1c5760405162461bcd60e51b8152602060048201526024808201527f43616e277420726566657220736f6d656f6e6520666f722074686973207365726044820152637669636560e01b60648201526084016108ca565b8a816001015403612c795760405162461bcd60e51b815260206004820152602160248201527f63616e27742063726561746520666f7220796f7572206f776e207365727669636044820152606560f81b60648201526084016108ca565b602e8614612c995760405162461bcd60e51b81526004016108ca90613dfd565b61013054604051631fff7f2760e11b8152600481018a90526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d08919061426b565b90506001600160a01b03811615612d585760008c8c8a8a604051602001612d329493929190614327565b604051602081830303815290604052805190602001209050612d5687878385612e02565b505b8315612dbb5761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015612da257600080fd5b505afa158015612db6573d6000803e3d6000fd5b505050505b505050505050505050505050565b600060143610801590612deb57503360009081526065602052604090205460ff165b15612dfd575060131936013560601c90565b503390565b6000612e5b836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000612e9f8287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061304d92505050565b9050806001600160a01b0316836001600160a01b031614611b245760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064016108ca565b612f008282611583565b61102057612f0d81613071565b612f18836020613083565b604051602001612f29929190614369565b60408051601f198184030181529082905262461bcd60e51b82526108ca916004016143de565b6001600160a01b0381163b612fbc5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108ca565b60008051602061443b83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b612ff483613226565b6000825111806130015750805b15610f91576130108383613266565b50505050565b600054610100900460ff1661303d5760405162461bcd60e51b81526004016108ca906142c9565b6114ac6130486123a9565b61292a565b600080600061305c858561335a565b915091506130698161339c565b509392505050565b606061081d6001600160a01b03831660145b606060006130928360026141ee565b61309d906002614314565b67ffffffffffffffff8111156130b5576130b56138d2565b6040519080825280601f01601f1916602001820160405280156130df576020820181803683370190505b509050600360fc1b816000815181106130fa576130fa6143f1565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613129576131296143f1565b60200101906001600160f81b031916908160001a905350600061314d8460026141ee565b613158906001614314565b90505b60018111156131d0576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061318c5761318c6143f1565b1a60f81b8282815181106131a2576131a26143f1565b60200101906001600160f81b031916908160001a90535060049490941c936131c981614407565b905061315b565b50831561321f5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108ca565b9392505050565b61322f81612f4f565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6132ce5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108ca565b600080846001600160a01b0316846040516132e9919061441e565b600060405180830381855af49150503d8060008114613324576040519150601f19603f3d011682016040523d82523d6000602084013e613329565b606091505b5091509150613351828260405180606001604052806027815260200161445b602791396134e6565b95945050505050565b60008082516041036133905760208301516040840151606085015160001a613384878285856134ff565b94509450505050611f5f565b50600090506002611f5f565b60008160048111156133b0576133b0613ad4565b036133b85750565b60018160048111156133cc576133cc613ad4565b036134195760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108ca565b600281600481111561342d5761342d613ad4565b0361347a5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108ca565b600381600481111561348e5761348e613ad4565b036111005760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108ca565b606083156134f557508161321f565b61321f83836135c3565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561353657506000905060036135ba565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561358a573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166135b3576000600192509250506135ba565b9150600090505b94509492505050565b8151156135d35781518083602001fd5b8060405162461bcd60e51b81526004016108ca91906143de565b60408051610100810190915280600081526020016000815260200160006001600160a01b0316815260200160008152602001600081526020016060815260200160008152602001600081525090565b6040805161010081019091528060008152602001600081526020016000815260200160608152602001600081526020016000815260200160006001600160a01b03168152602001600081525090565b60006020828403121561369d57600080fd5b81356001600160e01b03198116811461321f57600080fd5b600080604083850312156136c857600080fd5b50508035926020909101359150565b60008083601f8401126136e957600080fd5b50813567ffffffffffffffff81111561370157600080fd5b602083019150836020828501011115611f5f57600080fd5b600080600080600080600060c0888a03121561373457600080fd5b873596506020880135955060408801359450606088013567ffffffffffffffff81111561376057600080fd5b61376c8a828b016136d7565b989b979a50959895979660808701359660a0013595509350505050565b60006020828403121561379b57600080fd5b5035919050565b6001600160a01b038116811461110057600080fd5b6000602082840312156137c957600080fd5b813561321f816137a2565b60008060008060008060008060c0898b0312156137f057600080fd5b8835975060208901359650604089013567ffffffffffffffff8082111561381657600080fd5b6138228c838d016136d7565b909850965060608b013591508082111561383b57600080fd5b506138488b828c016136d7565b909550935050608089013561385c816137a2565b8092505060a089013590509295985092959890939650565b6000806040838503121561388757600080fd5b823591506020830135613899816137a2565b809150509250929050565b600080604083850312156138b757600080fd5b82356138c2816137a2565b91506020830135613899816137a2565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156138fb57600080fd5b8235613906816137a2565b9150602083013567ffffffffffffffff8082111561392357600080fd5b818501915085601f83011261393757600080fd5b813581811115613949576139496138d2565b604051601f8201601f19908116603f01168101908382118183101715613971576139716138d2565b8160405282815288602084870101111561398a57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b801515811461110057600080fd5b6000806000606084860312156139cf57600080fd5b83356139da816137a2565b925060208401356139ea816139ac565b929592945050506040919091013590565b6000806000806000806000806000806101008b8d031215613a1b57600080fd5b8a35995060208b0135985060408b0135975060608b0135965060808b013567ffffffffffffffff80821115613a4f57600080fd5b613a5b8e838f016136d7565b909850965060a08d0135955060c08d0135915080821115613a7b57600080fd5b50613a888d828e016136d7565b9150809450508092505060e08b013590509295989b9194979a5092959850565b600080600060608486031215613abd57600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052602160045260246000fd5b60028110613afa57613afa613ad4565b9052565b60005b83811015613b19578181015183820152602001613b01565b50506000910152565b60008151808452613b3a816020860160208601613afe565b601f01601f19169290920160200192915050565b6000610100613b5e848451613aea565b6020830151602085015260018060a01b036040840151166040850152606083015160608501526080830151608085015260a08301518160a0860152613ba582860182613b22565b91505060c083015160c085015260e083015160e08501528091505092915050565b60208152600061321f6020830184613b4e565b60058110613afa57613afa613ad4565b6000610100613bf8838c613bd9565b896020840152886040840152806060840152613c1681840189613b22565b6080840197909752505060a08101939093526001600160a01b039190911660c083015260e090910152949350505050565b6000610100613c56838c613aea565b89602084015260018060a01b03891660408401528760608401528660808401528060a0840152613c8881840187613b22565b60c0840195909552505060e001529695505050505050565b6000610100613cb0848451613bd9565b60208301516020850152604083015160408501526060830151816060860152613cdb82860182613b22565b6080858101519087015260a0808601519087015260c0808601516001600160a01b03169087015260e0948501519490950193909352509192915050565b604081526000613d2b6040830185613ca0565b82810360208401526133518185613b4e565b60208152600061321f6020830184613ca0565b600080600080600060808688031215613d6857600080fd5b853594506020860135935060408601359250606086013567ffffffffffffffff811115613d9457600080fd5b613da0888289016136d7565b969995985093965092949392505050565b600060208284031215613dc357600080fd5b815161321f816139ac565b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b6020808252600b908201526a125b9d985b1a590818da5960aa1b604082015260600190565b600181811c90821680613e3657607f821691505b602082108103613e5657634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610f9157600081815260208120601f850160051c81016020861015613e835750805b601f850160051c820191505b81811015611b2457828155600101613e8f565b67ffffffffffffffff831115613eba57613eba6138d2565b613ece83613ec88354613e22565b83613e5c565b6000601f841160018114613f025760008515613eea5750838201355b600019600387901b1c1916600186901b178355613f5c565b600083815260209020601f19861690835b82811015613f335786850135825560209485019460019092019101613f13565b5086821015613f505760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b87815286602082015260c060408201526000613fac60c083018789613f63565b606083019590955250608081019290925260a090910152949350505050565b634e487b7160e01b600052601160045260246000fd5b600060018201613ff357613ff3613fcb565b5060010190565b87815286602082015285604082015260c06060820152600061402060c083018688613f63565b6001600160a01b039490941660808301525060a0015295945050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b815167ffffffffffffffff8111156140f1576140f16138d2565b614105816140ff8454613e22565b84613e5c565b602080601f83116001811461413a57600084156141225750858301515b600019600386901b1c1916600185901b178555611b24565b600085815260208120601f198616915b828110156141695788860151825594840194600190910190840161414a565b50858210156141875787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006101008b83528a60208401528060408401526141b88184018a8c613f63565b9150506141c86060830188613aea565b8560808301528460a08301528360c08301528260e08301529a9950505050505050505050565b808202811582820484141761081d5761081d613fcb565b60008261422257634e487b7160e01b600052601260045260246000fd5b500490565b848152606060208201526000614241606083018587613f63565b905082604083015295945050505050565b60006020828403121561426457600080fd5b5051919050565b60006020828403121561427d57600080fd5b815161321f816137a2565b6c6372656174655365727669636560981b815284600d820152603b60f81b602d82015283602e8201528183604e83013760009101604e019081529392505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8082018082111561081d5761081d613fcb565b6d18dc99585d19541c9bdc1bdcd85b60921b815284600e820152603b60f81b602e82015283602f8201528183604f83013760009101604f019081529392505050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516143a1816017850160208801613afe565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516143d2816028840160208801613afe565b01602801949350505050565b60208152600061321f6020830184613b22565b634e487b7160e01b600052603260045260246000fd5b60008161441657614416613fcb565b506000190190565b60008251614430818460208701613afe565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220397b6e8ab583d064618d0d5b7fe3da4cfb56beab325a99d1a0fca57da22eb57e64736f6c63430008110033", "linkReferences": {}, "deployedLinkReferences": {} } From 2ec46fe2b4a14c418c7ddd8ab1b6fd551e147ab0 Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Wed, 29 Nov 2023 20:22:52 +0000 Subject: [PATCH 25/40] Updated referralAmount type number => string --- packages/client/src/services/index.ts | 4 ++-- packages/client/src/services/types/index.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/client/src/services/index.ts b/packages/client/src/services/index.ts index abd8ed6..4d152e9 100644 --- a/packages/client/src/services/index.ts +++ b/packages/client/src/services/index.ts @@ -72,7 +72,7 @@ export class Service implements IService { userId: string, platformId: number, token: string, - referralAmount: number = 0, + referralAmount: string = '0', ): Promise { const platformDetailsResponse = await this.graphQlClient.get( getPlatformById(this.platformID.toString()), @@ -105,7 +105,7 @@ export class Service implements IService { serviceDetails: ServiceDetails, userId: string, serviceId: number, - referralAmount: number = 0, + referralAmount: string = '0', ): Promise { const cid = await this.updloadServiceDataToIpfs(serviceDetails); diff --git a/packages/client/src/services/types/index.ts b/packages/client/src/services/types/index.ts index b70fa1f..ce294cf 100644 --- a/packages/client/src/services/types/index.ts +++ b/packages/client/src/services/types/index.ts @@ -8,13 +8,13 @@ export interface IService { userId: string, platformId: number, token: string, - referralAmount?: number, + referralAmount?: string, ): Promise; update( serviceDetails: ServiceDetails, userId: string, serviceId: number, - referralAmount?: number, + referralAmount?: string, ): Promise; updloadServiceDataToIpfs(serviceData: ServiceDetails): Promise; getServices(params: IProps): Promise; From 502df4b5292b533d67cbc3718249370bc1c30501 Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Thu, 30 Nov 2023 16:00:24 +0000 Subject: [PATCH 26/40] Added referral fees in allowance calculation --- packages/client/src/escrow/index.ts | 36 ++++++++++++++++++++--------- packages/client/src/utils/fees.ts | 10 ++++---- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/packages/client/src/escrow/index.ts b/packages/client/src/escrow/index.ts index eed7a68..ffc9e3e 100644 --- a/packages/client/src/escrow/index.ts +++ b/packages/client/src/escrow/index.ts @@ -1,13 +1,13 @@ -import { ERC20, IERC20 } from '../blockchain-bindings/erc20'; +import {ERC20, IERC20} from '../blockchain-bindings/erc20'; import GraphQLClient from '../graphql'; import IPFSClient from '../ipfs'; -import { Proposal } from '../proposals'; -import { Service } from '../services'; -import { ClientTransactionResponse, NetworkEnum, RateToken } from '../types'; -import { calculateApprovalAmount } from '../utils/fees'; -import { ViemClient } from '../viem'; -import { getPaymentsByService, getProtocolAndPlatformsFees } from './graphql/queries'; -import { IEscrow } from "./types"; +import {Proposal} from '../proposals'; +import {Service} from '../services'; +import {ClientTransactionResponse, NetworkEnum, RateToken} from '../types'; +import {calculateApprovalAmount} from '../utils/fees'; +import {ViemClient} from '../viem'; +import {getPaymentsByService, getProtocolAndPlatformsFees} from './graphql/queries'; +import {IEscrow} from "./types"; export class Escrow implements IEscrow { graphQlClient: GraphQLClient; @@ -44,13 +44,26 @@ export class Escrow implements IEscrow { this.viemClient, this.platformID, ); + + const serviceInstance = new Service( + this.graphQlClient, + this.ipfsClient, + this.viemClient, + this.platformID, + ); + const proposal = await proposalInstance.getOne(proposalId); + const service = await serviceInstance.getOne(serviceId); const erc20 = this.erc20; if (!proposal) { throw new Error('Proposal not found'); } + if (!service) { + throw new Error('Service not found'); + } + if (!proposal.cid) { throw new Error('Proposal cid not found'); } @@ -70,11 +83,14 @@ export class Escrow implements IEscrow { throw Error('Unable to fetch fees'); } + console.log('SDK: referral amount', service.referralAmount); + const approvalAmount = calculateApprovalAmount( proposal.rateAmount, protocolAndPlatformsFees.servicePlatform.originServiceFeeRate, protocolAndPlatformsFees.proposalPlatform.originValidatedProposalFeeRate, protocolAndPlatformsFees.protocols[0].protocolEscrowFeeRate, + service.referralAmount, ); console.log('SDK: escrow seeking approval for amount: ', approvalAmount.toString()); @@ -152,13 +168,11 @@ export class Escrow implements IEscrow { throw new Error('Transaction Id not found for service'); } - const tx = await this.viemClient.writeContract('talentLayerEscrow', 'release', [ + return await this.viemClient.writeContract('talentLayerEscrow', 'release', [ userId, parseInt(transactionId), amount.toString(), ]); - - return tx; } public async reimburse(serviceId: string, amount: bigint, userId: number): Promise { diff --git a/packages/client/src/utils/fees.ts b/packages/client/src/utils/fees.ts index 3ff5d4e..5ee776d 100644 --- a/packages/client/src/utils/fees.ts +++ b/packages/client/src/utils/fees.ts @@ -1,19 +1,17 @@ -import { FEE_RATE_DIVIDER } from '../constants'; +import {FEE_RATE_DIVIDER} from '../constants'; export const calculateApprovalAmount = ( proposalRateAmount: string, originServiceFeeRate: string, originValidatedProposalFeeRate: string, protocolEscrowFeeRate: string, + referralAmount: string, ): bigint => { - const jobRateAmount = BigInt(proposalRateAmount); + const jobRateAmount = BigInt(proposalRateAmount) + BigInt(referralAmount); const protocolFee = (jobRateAmount * BigInt(protocolEscrowFeeRate)) / BigInt(FEE_RATE_DIVIDER); const originServiceFee = (jobRateAmount * BigInt(originServiceFeeRate)) / BigInt(FEE_RATE_DIVIDER); const originValidatedProposalFee = (jobRateAmount * BigInt(originValidatedProposalFeeRate)) / BigInt(FEE_RATE_DIVIDER); - const totalAmount: bigint = - jobRateAmount + originServiceFee + originValidatedProposalFee + protocolFee; - - return totalAmount; + return jobRateAmount + originServiceFee + originValidatedProposalFee + protocolFee; }; From 9b916b585561eae51ffa9c61cf5098b42a2dd385 Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Fri, 1 Dec 2023 16:29:16 +0000 Subject: [PATCH 27/40] Updated updateService function --- .../src/contracts/ABI/TalentLayerService.json | 167 ++---------------- packages/client/src/services/index.ts | 3 +- packages/client/src/services/types/index.ts | 1 + 3 files changed, 18 insertions(+), 153 deletions(-) diff --git a/packages/client/src/contracts/ABI/TalentLayerService.json b/packages/client/src/contracts/ABI/TalentLayerService.json index bef5883..66f6380 100644 --- a/packages/client/src/contracts/ABI/TalentLayerService.json +++ b/packages/client/src/contracts/ABI/TalentLayerService.json @@ -8,154 +8,6 @@ "stateMutability": "nonpayable", "type": "constructor" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "id", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "ownerId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "platformId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "string", - "name": "dataUri", - "type": "string" - } - ], - "name": "ServiceCreated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "id", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "string", - "name": "dataUri", - "type": "string" - } - ], - "name": "ServiceDetailedUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "ownerId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "string", - "name": "dataUri", - "type": "string" - }, - { - "indexed": false, - "internalType": "enum TalentLayerService.ProposalStatus", - "name": "status", - "type": "uint8" - }, - { - "indexed": false, - "internalType": "address", - "name": "rateToken", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "rateAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "platformId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "expirationDate", - "type": "uint256" - } - ], - "name": "ProposalCreated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "ownerId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "string", - "name": "dataUri", - "type": "string" - }, - { - "indexed": false, - "internalType": "address", - "name": "rateToken", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "rateAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "expirationDate", - "type": "uint256" - } - ], - "name": "ProposalUpdated", - "type": "event" - }, { "anonymous": false, "inputs": [ @@ -288,7 +140,7 @@ { "indexed": false, "internalType": "uint256", - "name": "amount", + "name": "rateAmount", "type": "uint256" }, { @@ -337,7 +189,7 @@ { "indexed": false, "internalType": "uint256", - "name": "amount", + "name": "rateAmount", "type": "uint256" }, { @@ -502,6 +354,12 @@ "name": "dataUri", "type": "string" }, + { + "indexed": false, + "internalType": "address", + "name": "rateToken", + "type": "address" + }, { "indexed": false, "internalType": "uint256", @@ -1512,6 +1370,11 @@ "name": "_serviceId", "type": "uint256" }, + { + "internalType": "address", + "name": "_rateToken", + "type": "address" + }, { "internalType": "uint256", "name": "_referralAmount", @@ -1560,8 +1423,8 @@ "type": "function" } ], - "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6080516144b7620001206000396000818161102e0152818161106e015281816113250152818161136501526113f401526144b76000f3fe6080604052600436106102305760003560e01c8063715018a61161012e578063c22c4f43116100ab578063ef0e239b1161006f578063ef0e239b1461072e578063f2fde38b1461075b578063f6c53d9b1461077b578063f9eaee0d14610792578063ff420375146107cc57600080fd5b8063c22c4f431461064a578063c2cfee271461067e578063ccaa7d2a146106b2578063d4eee1fc146106e0578063d547741f1461070e57600080fd5b8063a217fddf116100f2578063a217fddf146105b5578063a24bd889146105ca578063a7d5eaea146105dd578063aba21009146105fd578063b5735c1e1461062a57600080fd5b8063715018a6146104f057806371da85f9146105055780637c5a72cd146105575780638da5cb5b1461057757806391d148541461059557600080fd5b80632f2ff15d116101bc578063485cc95511610180578063485cc9551461043b5780634f1ef2861461045b57806352d1902d1461046e578063572b6c05146104835780636ce76f30146104bc57600080fd5b80632f2ff15d1461039b57806336568abe146103bb5780633659cfe6146103db5780633751d89c146103fb5780633ca2ad6f1461041b57600080fd5b8063156b39aa11610203578063156b39aa146102e55780631db087ff1461030a578063248a9ca31461033857806326d00668146103685780632afaf2201461038857600080fd5b806301ffc9a714610235578063089b7c731461026a5780631499f9e61461028c578063154664ed146102c5575b600080fd5b34801561024157600080fd5b5061025561025036600461368b565b6107ec565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061028a6102853660046136b5565b610823565b005b34801561029857600080fd5b50610130546102ad906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b3480156102d157600080fd5b5061028a6102e0366004613719565b6109c6565b3480156102f157600080fd5b506102fc6101365481565b604051908152602001610261565b34801561031657600080fd5b506102fc610325366004613789565b6101336020526000908152604090205481565b34801561034457600080fd5b506102fc610353366004613789565b600090815260fc602052604090206001015490565b34801561037457600080fd5b5061028a6103833660046137b7565b610cde565b6102fc6103963660046137d4565b610d41565b3480156103a757600080fd5b5061028a6103b6366004613874565b610f6c565b3480156103c757600080fd5b5061028a6103d6366004613874565b610f96565b3480156103e757600080fd5b5061028a6103f63660046137b7565b611024565b34801561040757600080fd5b5061028a6104163660046137b7565b611103565b34801561042757600080fd5b5061028a610436366004613789565b61115c565b34801561044757600080fd5b5061028a6104563660046138a4565b6111a4565b61028a6104693660046138e8565b61131b565b34801561047a57600080fd5b506102fc6113e7565b34801561048f57600080fd5b5061025561049e3660046137b7565b6001600160a01b031660009081526065602052604090205460ff1690565b3480156104c857600080fd5b506102fc7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f81565b3480156104fc57600080fd5b5061028a61149a565b34801561051157600080fd5b506105406105203660046137b7565b610135602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610261565b34801561056357600080fd5b5061028a6105723660046139ba565b6114ae565b34801561058357600080fd5b506033546001600160a01b03166102ad565b3480156105a157600080fd5b506102556105b0366004613874565b611583565b3480156105c157600080fd5b506102fc600081565b61028a6105d83660046139fb565b6115ae565b3480156105e957600080fd5b5061028a6105f8366004613aa8565b6118c8565b34801561060957600080fd5b5061061d6106183660046136b5565b61194a565b6040516102619190613bc6565b34801561063657600080fd5b5061028a6106453660046136b5565b611a87565b34801561065657600080fd5b5061066a610665366004613789565b611b2c565b604051610261989796959493929190613be9565b34801561068a57600080fd5b5061069e6106993660046136b5565b611c09565b604051610261989796959493929190613c47565b3480156106be57600080fd5b506102fc6106cd366004613789565b6101346020526000908152604090205481565b3480156106ec57600080fd5b506107006106fb3660046136b5565b611cf0565b604051610261929190613d18565b34801561071a57600080fd5b5061028a610729366004613874565b611f66565b34801561073a57600080fd5b5061074e610749366004613789565b611f8b565b6040516102619190613d3d565b34801561076757600080fd5b5061028a6107763660046137b7565b61210b565b34801561078757600080fd5b506102fc61012e5481565b34801561079e57600080fd5b506102556107ad3660046137b7565b6001600160a01b03166000908152610135602052604090205460ff1690565b3480156107d857600080fd5b5061028a6107e7366004613d50565b612181565b60006001600160e01b03198216637965db0b60e01b148061081d57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61012f5482906001600160a01b0316632fa117e5826108406123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561088a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ae9190613db1565b6108d35760405162461bcd60e51b81526004016108ca90613dce565b60405180910390fd5b600082815261013160205260409020600181015484146109255760405162461bcd60e51b815260206004820152600d60248201526c3737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff16600481111561093d5761093d613ad4565b146109825760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b805460ff191660031781556040518381527f853aa4be1ac86f37acfc91d42b57f1fe895205aa6f8f9b7caa77ca257049ab1a9060200160405180910390a150505050565b61012f5487906001600160a01b0316632fa117e5826109e36123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a519190613db1565b610a6d5760405162461bcd60e51b81526004016108ca90613dce565b60008781526101316020908152604080832061013283528184208c855290925282209091825460ff166004811115610aa757610aa7613ad4565b14610ae95760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b89816001015414610b2c5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b602e8614610b4c5760405162461bcd60e51b81526004016108ca90613dfd565b6001815460ff166001811115610b6457610b64613ad4565b03610ba55760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481d985b1a59185d1959607a1b60448201526064016108ca565b60068201546001600160a01b031660009081526101356020526040902060010154881015610c065760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b8315610c695761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015610c5057600080fd5b505afa158015610c64573d6000803e3d6000fd5b505050505b6003810188905560058101610c7f878983613ea2565b5060068101859055600781018490556040517ffbfaa6f4e508bec40137ac265a7424e16a2d209355b2f4a35de5a80ba8fec1db90610cca908b908d908b908b908e908c908c90613f8c565b60405180910390a150505050505050505050565b610ce66123b8565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b61012f5460009089906001600160a01b0316632fa117e582610d616123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610dab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcf9190613db1565b610deb5760405162461bcd60e51b81526004016108ca90613dce565b610dfa8a8a8a8a8a8a8a612431565b61012e80549081906000610e0d83613fe1565b9091555050600081815261013160205260409020805460ff19168155600181018c905560038101610e3f8a8c83613ea2565b50600581018b90556006810180546001600160a01b0319166001600160a01b0388161790556007810185905560008c81526101336020526040902054158015610e95575060008c81526101346020526040902054155b15610efa5761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015610ee157600080fd5b505af1158015610ef5573d6000803e3d6000fd5b505050505b60008c815261013360205260408120805491610f1583613fe1565b91905055507fe7f6435fc92b0ccd6f56395ae67b06f2cdb9680c0179f87f5821431304ad3f3e828d8d8d8d8b8b604051610f559796959493929190613ffa565b60405180910390a1509a9950505050505050505050565b600082815260fc6020526040902060010154610f878161263a565b610f91838361264b565b505050565b610f9e6123a9565b6001600160a01b0316816001600160a01b0316146110165760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108ca565b61102082826126d2565b5050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361106c5760405162461bcd60e51b81526004016108ca9061403f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166110b560008051602061443b833981519152546001600160a01b031690565b6001600160a01b0316146110db5760405162461bcd60e51b81526004016108ca9061408b565b6110e481612757565b604080516000808252602082019092526111009183919061275f565b50565b61110b6123b8565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee69101610d36565b60006111678161263a565b6101368290556040518281527f577d7afcf67637a2f602cba220bbb292c1d715380dd011bfec748c3f641b2fd29060200160405180910390a15050565b600054610100900460ff16158080156111c45750600054600160ff909116105b806111de5750303b1580156111de575060005460ff166001145b6112415760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108ca565b6000805460ff191660011790558015611264576000805461ff0019166101001790555b61126c6128ca565b6112746128f9565b61127c6128f9565b61128e60006112896123a9565b612920565b61012f80546001600160a01b038086166001600160a01b031992831617909255610130805492851692909116919091179055600161012e556112d0601e61115c565b8015610f91576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036113635760405162461bcd60e51b81526004016108ca9061403f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166113ac60008051602061443b833981519152546001600160a01b031690565b6001600160a01b0316146113d25760405162461bcd60e51b81526004016108ca9061408b565b6113db82612757565b6110208282600161275f565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146114875760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108ca565b5060008051602061443b83398151915290565b6114a26123b8565b6114ac600061292a565b565b6114b66123b8565b6001600160a01b0383161580156114cb575081155b156115185760405162461bcd60e51b815260206004820152601d60248201527f4f776e65722063616e27742072656d6f7665204f78206164647265737300000060448201526064016108ca565b6001600160a01b03831660008181526101356020908152604091829020805460ff19168615159081178255600190910185905582519384529083015281018290527f42b585a1da1cff4b571e7a78aea1b4601b1d128de41a0feebd8a77aaf48b9d889060600161130e565b600091825260fc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61012f548a906001600160a01b0316632fa117e5826115cb6123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611615573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116399190613db1565b6116555760405162461bcd60e51b81526004016108ca90613dce565b60008a8152610131602052604090206116758c8c8c8c8c8c8b8b8b61297c565b60408051610100810182526000815260208082018f905260068401546001600160a01b031682840152606082018d9052608082018c90528251601f8b01829004820281018201909352898352909160a08301918b908b9081908401838280828437600081840152601f19601f8201169050808301925050505050505081526020018781526020018481525061013260008d815260200190815260200160002060008e815260200190815260200160002060008201518160000160006101000a81548160ff0219169083600181111561174f5761174f613ad4565b02179055506020820151600182015560408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a082015160058201906117ac90826140d7565b5060c0820151600682015560e09091015160079091015560008c815261013360205260409020541580156117ed575060008c81526101346020526040902054155b156118525761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b15801561183957600080fd5b505af115801561184d573d6000803e3d6000fd5b505050505b60008c81526101346020526040812080549161186d83613fe1565b91905055507fabd26455c3256ad90125661f4c1a4c16fecf585ccade21e749c56d8fd44bb1dd8b8d8a8a60008f8f8d8b6040516118b299989796959493929190614197565b60405180910390a1505050505050505050505050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f6118f28161263a565b60008481526101316020908152604080832061013283528184208785529092529091208154600160ff1991821681178455808301546002850155600484018690558254909183911682805b0217905550505050505050565b6119526135ed565b60008381526101326020908152604080832085845290915290819020815161010081019092528054829060ff16600181111561199057611990613ad4565b60018111156119a1576119a1613ad4565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a0909201916119e990613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611a1590613e22565b8015611a625780601f10611a3757610100808354040283529160200191611a62565b820191906000526020600020905b815481529060010190602001808311611a4557829003601f168201915b5050505050815260200160068201548152602001600782015481525050905092915050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611ab18161263a565b6000838152610131602090815260408083206101328352818420600282015485529092528220600381015491929091611aeb8660646141ee565b611af59190614205565b9050610136548110611b1157825460ff19166002178355611b24565b8254600490849060ff191660018361193d565b505050505050565b61013160205260009081526040902080546001820154600283015460038401805460ff909416949293919291611b6190613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611b8d90613e22565b8015611bda5780601f10611baf57610100808354040283529160200191611bda565b820191906000526020600020905b815481529060010190602001808311611bbd57829003601f168201915b505050600484015460058501546006860154600790960154949591949093506001600160a01b03909116915088565b61013260209081526000928352604080842090915290825290208054600182015460028301546003840154600485015460058601805460ff9096169694956001600160a01b03909416949293919291611c6190613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611c8d90613e22565b8015611cda5780601f10611caf57610100808354040283529160200191611cda565b820191906000526020600020905b815481529060010190602001808311611cbd57829003601f168201915b5050505050908060060154908060070154905088565b611cf861363c565b611d006135ed565b60008481526101316020526040808220815161010081019092528054829060ff166004811115611d3257611d32613ad4565b6004811115611d4357611d43613ad4565b81526020016001820154815260200160028201548152602001600382018054611d6b90613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611d9790613e22565b8015611de45780601f10611db957610100808354040283529160200191611de4565b820191906000526020600020905b815481529060010190602001808311611dc757829003601f168201915b50505091835250506004820154602080830191909152600583015460408084019190915260068401546001600160a01b03166060840152600790930154608090920191909152600088815261013282528281208882529091528181208251610100810190935280549394509092829060ff166001811115611e6757611e67613ad4565b6001811115611e7857611e78613ad4565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611ec090613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611eec90613e22565b8015611f395780601f10611f0e57610100808354040283529160200191611f39565b820191906000526020600020905b815481529060010190602001808311611f1c57829003601f168201915b505050918352505060068201546020820152600790910154604090910152919350909150505b9250929050565b600082815260fc6020526040902060010154611f818161263a565b610f9183836126d2565b611f9361363c565b61012e548210611fe55760405162461bcd60e51b815260206004820152601a60248201527f54686973207365727669636520646f65736e277420657869737400000000000060448201526064016108ca565b6000828152610131602052604090819020815161010081019092528054829060ff16600481111561201857612018613ad4565b600481111561202957612029613ad4565b8152602001600182015481526020016002820154815260200160038201805461205190613e22565b80601f016020809104026020016040519081016040528092919081815260200182805461207d90613e22565b80156120ca5780601f1061209f576101008083540402835291602001916120ca565b820191906000526020600020905b8154815290600101906020018083116120ad57829003601f168201915b5050509183525050600482015460208201526005820154604082015260068201546001600160a01b0316606082015260079091015460809091015292915050565b6121136123b8565b6001600160a01b0381166121785760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108ca565b6111008161292a565b61012f5485906001600160a01b0316632fa117e58261219e6123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156121e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220c9190613db1565b6122285760405162461bcd60e51b81526004016108ca90613dce565b6000858152610131602052604090206001810154871461227a5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff16600481111561229257612292613ad4565b146122d75760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b602e83146122f75760405162461bcd60e51b81526004016108ca90613dfd565b806007015485101561234b5760405162461bcd60e51b815260206004820152601c60248201527f43616e27742072656475636520726566657272616c20616d6f756e740000000060448201526064016108ca565b6003810161235a848683613ea2565b50600781018590556040517fae55ce3c351e2400a1a143e7ed66668e581e1656ad1797a317e415d03588091690612398908890879087908a90614227565b60405180910390a150505050505050565b60006123b3612dc9565b905090565b6123c06123a9565b6001600160a01b03166123db6033546001600160a01b031690565b6001600160a01b0316146114ac5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108ca565b61013054604051638a98636360e01b8152600481018890526000916001600160a01b031690638a98636390602401602060405180830381865afa15801561247c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a09190614252565b90508034146124e65760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b602e85146125065760405162461bcd60e51b81526004016108ca90613dfd565b6001600160a01b0382166000908152610135602052604090205460ff166125635760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108ca565b61013054604051631fff7f2760e11b8152600481018990526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa1580156125ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d2919061426b565b90506001600160a01b0381161561262f57600089815261013360209081526040808320549051612609928d92918c918c9101614288565b60405160208183030381529060405280519060200120905061262d86868385612e02565b505b505050505050505050565b611100816126466123a9565b612ef6565b6126558282611583565b61102057600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561268e6123a9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6126dc8282611583565b1561102057600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191690556127136123a9565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6111006123b8565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561279257610f9183612f4f565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156127ec575060408051601f3d908101601f191682019092526127e991810190614252565b60015b61284f5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108ca565b60008051602061443b83398151915281146128be5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108ca565b50610f91838383612feb565b600054610100900460ff166128f15760405162461bcd60e51b81526004016108ca906142c9565b6114ac613016565b600054610100900460ff166114ac5760405162461bcd60e51b81526004016108ca906142c9565b611020828261264b565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61013054604051634a7ab1d560e01b8152600481018890526000916001600160a01b031690634a7ab1d590602401602060405180830381865afa1580156129c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129eb9190614252565b9050803414612a315760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b60008981526101316020908152604080832060068101546001600160a01b03168452610135909252909120600101546007820154612a6f908b614314565b1015612aae5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b6000815460ff166004811115612ac657612ac6613ad4565b14612b085760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b8060010154600003612b505760405162461bcd60e51b815260206004820152601160248201527014d95c9d9a58d9481b9bdd08195e1a5cdd607a1b60448201526064016108ca565b60008a8152610132602090815260408083208e84529091529020600101548b9003612bb65760405162461bcd60e51b81526020600482015260166024820152751c1c9bdc1bdcd85b08185b1c9958591e48195e1a5cdd60521b60448201526064016108ca565b8215612c1c576000816007015411612c1c5760405162461bcd60e51b8152602060048201526024808201527f43616e277420726566657220736f6d656f6e6520666f722074686973207365726044820152637669636560e01b60648201526084016108ca565b8a816001015403612c795760405162461bcd60e51b815260206004820152602160248201527f63616e27742063726561746520666f7220796f7572206f776e207365727669636044820152606560f81b60648201526084016108ca565b602e8614612c995760405162461bcd60e51b81526004016108ca90613dfd565b61013054604051631fff7f2760e11b8152600481018a90526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d08919061426b565b90506001600160a01b03811615612d585760008c8c8a8a604051602001612d329493929190614327565b604051602081830303815290604052805190602001209050612d5687878385612e02565b505b8315612dbb5761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015612da257600080fd5b505afa158015612db6573d6000803e3d6000fd5b505050505b505050505050505050505050565b600060143610801590612deb57503360009081526065602052604090205460ff165b15612dfd575060131936013560601c90565b503390565b6000612e5b836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000612e9f8287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061304d92505050565b9050806001600160a01b0316836001600160a01b031614611b245760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064016108ca565b612f008282611583565b61102057612f0d81613071565b612f18836020613083565b604051602001612f29929190614369565b60408051601f198184030181529082905262461bcd60e51b82526108ca916004016143de565b6001600160a01b0381163b612fbc5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108ca565b60008051602061443b83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b612ff483613226565b6000825111806130015750805b15610f91576130108383613266565b50505050565b600054610100900460ff1661303d5760405162461bcd60e51b81526004016108ca906142c9565b6114ac6130486123a9565b61292a565b600080600061305c858561335a565b915091506130698161339c565b509392505050565b606061081d6001600160a01b03831660145b606060006130928360026141ee565b61309d906002614314565b67ffffffffffffffff8111156130b5576130b56138d2565b6040519080825280601f01601f1916602001820160405280156130df576020820181803683370190505b509050600360fc1b816000815181106130fa576130fa6143f1565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613129576131296143f1565b60200101906001600160f81b031916908160001a905350600061314d8460026141ee565b613158906001614314565b90505b60018111156131d0576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061318c5761318c6143f1565b1a60f81b8282815181106131a2576131a26143f1565b60200101906001600160f81b031916908160001a90535060049490941c936131c981614407565b905061315b565b50831561321f5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108ca565b9392505050565b61322f81612f4f565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6132ce5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108ca565b600080846001600160a01b0316846040516132e9919061441e565b600060405180830381855af49150503d8060008114613324576040519150601f19603f3d011682016040523d82523d6000602084013e613329565b606091505b5091509150613351828260405180606001604052806027815260200161445b602791396134e6565b95945050505050565b60008082516041036133905760208301516040840151606085015160001a613384878285856134ff565b94509450505050611f5f565b50600090506002611f5f565b60008160048111156133b0576133b0613ad4565b036133b85750565b60018160048111156133cc576133cc613ad4565b036134195760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108ca565b600281600481111561342d5761342d613ad4565b0361347a5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108ca565b600381600481111561348e5761348e613ad4565b036111005760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108ca565b606083156134f557508161321f565b61321f83836135c3565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561353657506000905060036135ba565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561358a573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166135b3576000600192509250506135ba565b9150600090505b94509492505050565b8151156135d35781518083602001fd5b8060405162461bcd60e51b81526004016108ca91906143de565b60408051610100810190915280600081526020016000815260200160006001600160a01b0316815260200160008152602001600081526020016060815260200160008152602001600081525090565b6040805161010081019091528060008152602001600081526020016000815260200160608152602001600081526020016000815260200160006001600160a01b03168152602001600081525090565b60006020828403121561369d57600080fd5b81356001600160e01b03198116811461321f57600080fd5b600080604083850312156136c857600080fd5b50508035926020909101359150565b60008083601f8401126136e957600080fd5b50813567ffffffffffffffff81111561370157600080fd5b602083019150836020828501011115611f5f57600080fd5b600080600080600080600060c0888a03121561373457600080fd5b873596506020880135955060408801359450606088013567ffffffffffffffff81111561376057600080fd5b61376c8a828b016136d7565b989b979a50959895979660808701359660a0013595509350505050565b60006020828403121561379b57600080fd5b5035919050565b6001600160a01b038116811461110057600080fd5b6000602082840312156137c957600080fd5b813561321f816137a2565b60008060008060008060008060c0898b0312156137f057600080fd5b8835975060208901359650604089013567ffffffffffffffff8082111561381657600080fd5b6138228c838d016136d7565b909850965060608b013591508082111561383b57600080fd5b506138488b828c016136d7565b909550935050608089013561385c816137a2565b8092505060a089013590509295985092959890939650565b6000806040838503121561388757600080fd5b823591506020830135613899816137a2565b809150509250929050565b600080604083850312156138b757600080fd5b82356138c2816137a2565b91506020830135613899816137a2565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156138fb57600080fd5b8235613906816137a2565b9150602083013567ffffffffffffffff8082111561392357600080fd5b818501915085601f83011261393757600080fd5b813581811115613949576139496138d2565b604051601f8201601f19908116603f01168101908382118183101715613971576139716138d2565b8160405282815288602084870101111561398a57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b801515811461110057600080fd5b6000806000606084860312156139cf57600080fd5b83356139da816137a2565b925060208401356139ea816139ac565b929592945050506040919091013590565b6000806000806000806000806000806101008b8d031215613a1b57600080fd5b8a35995060208b0135985060408b0135975060608b0135965060808b013567ffffffffffffffff80821115613a4f57600080fd5b613a5b8e838f016136d7565b909850965060a08d0135955060c08d0135915080821115613a7b57600080fd5b50613a888d828e016136d7565b9150809450508092505060e08b013590509295989b9194979a5092959850565b600080600060608486031215613abd57600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052602160045260246000fd5b60028110613afa57613afa613ad4565b9052565b60005b83811015613b19578181015183820152602001613b01565b50506000910152565b60008151808452613b3a816020860160208601613afe565b601f01601f19169290920160200192915050565b6000610100613b5e848451613aea565b6020830151602085015260018060a01b036040840151166040850152606083015160608501526080830151608085015260a08301518160a0860152613ba582860182613b22565b91505060c083015160c085015260e083015160e08501528091505092915050565b60208152600061321f6020830184613b4e565b60058110613afa57613afa613ad4565b6000610100613bf8838c613bd9565b896020840152886040840152806060840152613c1681840189613b22565b6080840197909752505060a08101939093526001600160a01b039190911660c083015260e090910152949350505050565b6000610100613c56838c613aea565b89602084015260018060a01b03891660408401528760608401528660808401528060a0840152613c8881840187613b22565b60c0840195909552505060e001529695505050505050565b6000610100613cb0848451613bd9565b60208301516020850152604083015160408501526060830151816060860152613cdb82860182613b22565b6080858101519087015260a0808601519087015260c0808601516001600160a01b03169087015260e0948501519490950193909352509192915050565b604081526000613d2b6040830185613ca0565b82810360208401526133518185613b4e565b60208152600061321f6020830184613ca0565b600080600080600060808688031215613d6857600080fd5b853594506020860135935060408601359250606086013567ffffffffffffffff811115613d9457600080fd5b613da0888289016136d7565b969995985093965092949392505050565b600060208284031215613dc357600080fd5b815161321f816139ac565b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b6020808252600b908201526a125b9d985b1a590818da5960aa1b604082015260600190565b600181811c90821680613e3657607f821691505b602082108103613e5657634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610f9157600081815260208120601f850160051c81016020861015613e835750805b601f850160051c820191505b81811015611b2457828155600101613e8f565b67ffffffffffffffff831115613eba57613eba6138d2565b613ece83613ec88354613e22565b83613e5c565b6000601f841160018114613f025760008515613eea5750838201355b600019600387901b1c1916600186901b178355613f5c565b600083815260209020601f19861690835b82811015613f335786850135825560209485019460019092019101613f13565b5086821015613f505760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b87815286602082015260c060408201526000613fac60c083018789613f63565b606083019590955250608081019290925260a090910152949350505050565b634e487b7160e01b600052601160045260246000fd5b600060018201613ff357613ff3613fcb565b5060010190565b87815286602082015285604082015260c06060820152600061402060c083018688613f63565b6001600160a01b039490941660808301525060a0015295945050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b815167ffffffffffffffff8111156140f1576140f16138d2565b614105816140ff8454613e22565b84613e5c565b602080601f83116001811461413a57600084156141225750858301515b600019600386901b1c1916600185901b178555611b24565b600085815260208120601f198616915b828110156141695788860151825594840194600190910190840161414a565b50858210156141875787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006101008b83528a60208401528060408401526141b88184018a8c613f63565b9150506141c86060830188613aea565b8560808301528460a08301528360c08301528260e08301529a9950505050505050505050565b808202811582820484141761081d5761081d613fcb565b60008261422257634e487b7160e01b600052601260045260246000fd5b500490565b848152606060208201526000614241606083018587613f63565b905082604083015295945050505050565b60006020828403121561426457600080fd5b5051919050565b60006020828403121561427d57600080fd5b815161321f816137a2565b6c6372656174655365727669636560981b815284600d820152603b60f81b602d82015283602e8201528183604e83013760009101604e019081529392505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8082018082111561081d5761081d613fcb565b6d18dc99585d19541c9bdc1bdcd85b60921b815284600e820152603b60f81b602e82015283602f8201528183604f83013760009101604f019081529392505050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516143a1816017850160208801613afe565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516143d2816028840160208801613afe565b01602801949350505050565b60208152600061321f6020830184613b22565b634e487b7160e01b600052603260045260246000fd5b60008161441657614416613fcb565b506000190190565b60008251614430818460208701613afe565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220397b6e8ab583d064618d0d5b7fe3da4cfb56beab325a99d1a0fca57da22eb57e64736f6c63430008110033", - "deployedBytecode": "0x6080604052600436106102305760003560e01c8063715018a61161012e578063c22c4f43116100ab578063ef0e239b1161006f578063ef0e239b1461072e578063f2fde38b1461075b578063f6c53d9b1461077b578063f9eaee0d14610792578063ff420375146107cc57600080fd5b8063c22c4f431461064a578063c2cfee271461067e578063ccaa7d2a146106b2578063d4eee1fc146106e0578063d547741f1461070e57600080fd5b8063a217fddf116100f2578063a217fddf146105b5578063a24bd889146105ca578063a7d5eaea146105dd578063aba21009146105fd578063b5735c1e1461062a57600080fd5b8063715018a6146104f057806371da85f9146105055780637c5a72cd146105575780638da5cb5b1461057757806391d148541461059557600080fd5b80632f2ff15d116101bc578063485cc95511610180578063485cc9551461043b5780634f1ef2861461045b57806352d1902d1461046e578063572b6c05146104835780636ce76f30146104bc57600080fd5b80632f2ff15d1461039b57806336568abe146103bb5780633659cfe6146103db5780633751d89c146103fb5780633ca2ad6f1461041b57600080fd5b8063156b39aa11610203578063156b39aa146102e55780631db087ff1461030a578063248a9ca31461033857806326d00668146103685780632afaf2201461038857600080fd5b806301ffc9a714610235578063089b7c731461026a5780631499f9e61461028c578063154664ed146102c5575b600080fd5b34801561024157600080fd5b5061025561025036600461368b565b6107ec565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061028a6102853660046136b5565b610823565b005b34801561029857600080fd5b50610130546102ad906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b3480156102d157600080fd5b5061028a6102e0366004613719565b6109c6565b3480156102f157600080fd5b506102fc6101365481565b604051908152602001610261565b34801561031657600080fd5b506102fc610325366004613789565b6101336020526000908152604090205481565b34801561034457600080fd5b506102fc610353366004613789565b600090815260fc602052604090206001015490565b34801561037457600080fd5b5061028a6103833660046137b7565b610cde565b6102fc6103963660046137d4565b610d41565b3480156103a757600080fd5b5061028a6103b6366004613874565b610f6c565b3480156103c757600080fd5b5061028a6103d6366004613874565b610f96565b3480156103e757600080fd5b5061028a6103f63660046137b7565b611024565b34801561040757600080fd5b5061028a6104163660046137b7565b611103565b34801561042757600080fd5b5061028a610436366004613789565b61115c565b34801561044757600080fd5b5061028a6104563660046138a4565b6111a4565b61028a6104693660046138e8565b61131b565b34801561047a57600080fd5b506102fc6113e7565b34801561048f57600080fd5b5061025561049e3660046137b7565b6001600160a01b031660009081526065602052604090205460ff1690565b3480156104c857600080fd5b506102fc7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f81565b3480156104fc57600080fd5b5061028a61149a565b34801561051157600080fd5b506105406105203660046137b7565b610135602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610261565b34801561056357600080fd5b5061028a6105723660046139ba565b6114ae565b34801561058357600080fd5b506033546001600160a01b03166102ad565b3480156105a157600080fd5b506102556105b0366004613874565b611583565b3480156105c157600080fd5b506102fc600081565b61028a6105d83660046139fb565b6115ae565b3480156105e957600080fd5b5061028a6105f8366004613aa8565b6118c8565b34801561060957600080fd5b5061061d6106183660046136b5565b61194a565b6040516102619190613bc6565b34801561063657600080fd5b5061028a6106453660046136b5565b611a87565b34801561065657600080fd5b5061066a610665366004613789565b611b2c565b604051610261989796959493929190613be9565b34801561068a57600080fd5b5061069e6106993660046136b5565b611c09565b604051610261989796959493929190613c47565b3480156106be57600080fd5b506102fc6106cd366004613789565b6101346020526000908152604090205481565b3480156106ec57600080fd5b506107006106fb3660046136b5565b611cf0565b604051610261929190613d18565b34801561071a57600080fd5b5061028a610729366004613874565b611f66565b34801561073a57600080fd5b5061074e610749366004613789565b611f8b565b6040516102619190613d3d565b34801561076757600080fd5b5061028a6107763660046137b7565b61210b565b34801561078757600080fd5b506102fc61012e5481565b34801561079e57600080fd5b506102556107ad3660046137b7565b6001600160a01b03166000908152610135602052604090205460ff1690565b3480156107d857600080fd5b5061028a6107e7366004613d50565b612181565b60006001600160e01b03198216637965db0b60e01b148061081d57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61012f5482906001600160a01b0316632fa117e5826108406123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561088a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ae9190613db1565b6108d35760405162461bcd60e51b81526004016108ca90613dce565b60405180910390fd5b600082815261013160205260409020600181015484146109255760405162461bcd60e51b815260206004820152600d60248201526c3737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff16600481111561093d5761093d613ad4565b146109825760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b805460ff191660031781556040518381527f853aa4be1ac86f37acfc91d42b57f1fe895205aa6f8f9b7caa77ca257049ab1a9060200160405180910390a150505050565b61012f5487906001600160a01b0316632fa117e5826109e36123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a519190613db1565b610a6d5760405162461bcd60e51b81526004016108ca90613dce565b60008781526101316020908152604080832061013283528184208c855290925282209091825460ff166004811115610aa757610aa7613ad4565b14610ae95760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b89816001015414610b2c5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b602e8614610b4c5760405162461bcd60e51b81526004016108ca90613dfd565b6001815460ff166001811115610b6457610b64613ad4565b03610ba55760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481d985b1a59185d1959607a1b60448201526064016108ca565b60068201546001600160a01b031660009081526101356020526040902060010154881015610c065760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b8315610c695761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015610c5057600080fd5b505afa158015610c64573d6000803e3d6000fd5b505050505b6003810188905560058101610c7f878983613ea2565b5060068101859055600781018490556040517ffbfaa6f4e508bec40137ac265a7424e16a2d209355b2f4a35de5a80ba8fec1db90610cca908b908d908b908b908e908c908c90613f8c565b60405180910390a150505050505050505050565b610ce66123b8565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b61012f5460009089906001600160a01b0316632fa117e582610d616123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610dab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcf9190613db1565b610deb5760405162461bcd60e51b81526004016108ca90613dce565b610dfa8a8a8a8a8a8a8a612431565b61012e80549081906000610e0d83613fe1565b9091555050600081815261013160205260409020805460ff19168155600181018c905560038101610e3f8a8c83613ea2565b50600581018b90556006810180546001600160a01b0319166001600160a01b0388161790556007810185905560008c81526101336020526040902054158015610e95575060008c81526101346020526040902054155b15610efa5761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015610ee157600080fd5b505af1158015610ef5573d6000803e3d6000fd5b505050505b60008c815261013360205260408120805491610f1583613fe1565b91905055507fe7f6435fc92b0ccd6f56395ae67b06f2cdb9680c0179f87f5821431304ad3f3e828d8d8d8d8b8b604051610f559796959493929190613ffa565b60405180910390a1509a9950505050505050505050565b600082815260fc6020526040902060010154610f878161263a565b610f91838361264b565b505050565b610f9e6123a9565b6001600160a01b0316816001600160a01b0316146110165760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108ca565b61102082826126d2565b5050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361106c5760405162461bcd60e51b81526004016108ca9061403f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166110b560008051602061443b833981519152546001600160a01b031690565b6001600160a01b0316146110db5760405162461bcd60e51b81526004016108ca9061408b565b6110e481612757565b604080516000808252602082019092526111009183919061275f565b50565b61110b6123b8565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee69101610d36565b60006111678161263a565b6101368290556040518281527f577d7afcf67637a2f602cba220bbb292c1d715380dd011bfec748c3f641b2fd29060200160405180910390a15050565b600054610100900460ff16158080156111c45750600054600160ff909116105b806111de5750303b1580156111de575060005460ff166001145b6112415760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108ca565b6000805460ff191660011790558015611264576000805461ff0019166101001790555b61126c6128ca565b6112746128f9565b61127c6128f9565b61128e60006112896123a9565b612920565b61012f80546001600160a01b038086166001600160a01b031992831617909255610130805492851692909116919091179055600161012e556112d0601e61115c565b8015610f91576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036113635760405162461bcd60e51b81526004016108ca9061403f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166113ac60008051602061443b833981519152546001600160a01b031690565b6001600160a01b0316146113d25760405162461bcd60e51b81526004016108ca9061408b565b6113db82612757565b6110208282600161275f565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146114875760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108ca565b5060008051602061443b83398151915290565b6114a26123b8565b6114ac600061292a565b565b6114b66123b8565b6001600160a01b0383161580156114cb575081155b156115185760405162461bcd60e51b815260206004820152601d60248201527f4f776e65722063616e27742072656d6f7665204f78206164647265737300000060448201526064016108ca565b6001600160a01b03831660008181526101356020908152604091829020805460ff19168615159081178255600190910185905582519384529083015281018290527f42b585a1da1cff4b571e7a78aea1b4601b1d128de41a0feebd8a77aaf48b9d889060600161130e565b600091825260fc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61012f548a906001600160a01b0316632fa117e5826115cb6123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611615573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116399190613db1565b6116555760405162461bcd60e51b81526004016108ca90613dce565b60008a8152610131602052604090206116758c8c8c8c8c8c8b8b8b61297c565b60408051610100810182526000815260208082018f905260068401546001600160a01b031682840152606082018d9052608082018c90528251601f8b01829004820281018201909352898352909160a08301918b908b9081908401838280828437600081840152601f19601f8201169050808301925050505050505081526020018781526020018481525061013260008d815260200190815260200160002060008e815260200190815260200160002060008201518160000160006101000a81548160ff0219169083600181111561174f5761174f613ad4565b02179055506020820151600182015560408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a082015160058201906117ac90826140d7565b5060c0820151600682015560e09091015160079091015560008c815261013360205260409020541580156117ed575060008c81526101346020526040902054155b156118525761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b15801561183957600080fd5b505af115801561184d573d6000803e3d6000fd5b505050505b60008c81526101346020526040812080549161186d83613fe1565b91905055507fabd26455c3256ad90125661f4c1a4c16fecf585ccade21e749c56d8fd44bb1dd8b8d8a8a60008f8f8d8b6040516118b299989796959493929190614197565b60405180910390a1505050505050505050505050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f6118f28161263a565b60008481526101316020908152604080832061013283528184208785529092529091208154600160ff1991821681178455808301546002850155600484018690558254909183911682805b0217905550505050505050565b6119526135ed565b60008381526101326020908152604080832085845290915290819020815161010081019092528054829060ff16600181111561199057611990613ad4565b60018111156119a1576119a1613ad4565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a0909201916119e990613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611a1590613e22565b8015611a625780601f10611a3757610100808354040283529160200191611a62565b820191906000526020600020905b815481529060010190602001808311611a4557829003601f168201915b5050505050815260200160068201548152602001600782015481525050905092915050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611ab18161263a565b6000838152610131602090815260408083206101328352818420600282015485529092528220600381015491929091611aeb8660646141ee565b611af59190614205565b9050610136548110611b1157825460ff19166002178355611b24565b8254600490849060ff191660018361193d565b505050505050565b61013160205260009081526040902080546001820154600283015460038401805460ff909416949293919291611b6190613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611b8d90613e22565b8015611bda5780601f10611baf57610100808354040283529160200191611bda565b820191906000526020600020905b815481529060010190602001808311611bbd57829003601f168201915b505050600484015460058501546006860154600790960154949591949093506001600160a01b03909116915088565b61013260209081526000928352604080842090915290825290208054600182015460028301546003840154600485015460058601805460ff9096169694956001600160a01b03909416949293919291611c6190613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611c8d90613e22565b8015611cda5780601f10611caf57610100808354040283529160200191611cda565b820191906000526020600020905b815481529060010190602001808311611cbd57829003601f168201915b5050505050908060060154908060070154905088565b611cf861363c565b611d006135ed565b60008481526101316020526040808220815161010081019092528054829060ff166004811115611d3257611d32613ad4565b6004811115611d4357611d43613ad4565b81526020016001820154815260200160028201548152602001600382018054611d6b90613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611d9790613e22565b8015611de45780601f10611db957610100808354040283529160200191611de4565b820191906000526020600020905b815481529060010190602001808311611dc757829003601f168201915b50505091835250506004820154602080830191909152600583015460408084019190915260068401546001600160a01b03166060840152600790930154608090920191909152600088815261013282528281208882529091528181208251610100810190935280549394509092829060ff166001811115611e6757611e67613ad4565b6001811115611e7857611e78613ad4565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611ec090613e22565b80601f0160208091040260200160405190810160405280929190818152602001828054611eec90613e22565b8015611f395780601f10611f0e57610100808354040283529160200191611f39565b820191906000526020600020905b815481529060010190602001808311611f1c57829003601f168201915b505050918352505060068201546020820152600790910154604090910152919350909150505b9250929050565b600082815260fc6020526040902060010154611f818161263a565b610f9183836126d2565b611f9361363c565b61012e548210611fe55760405162461bcd60e51b815260206004820152601a60248201527f54686973207365727669636520646f65736e277420657869737400000000000060448201526064016108ca565b6000828152610131602052604090819020815161010081019092528054829060ff16600481111561201857612018613ad4565b600481111561202957612029613ad4565b8152602001600182015481526020016002820154815260200160038201805461205190613e22565b80601f016020809104026020016040519081016040528092919081815260200182805461207d90613e22565b80156120ca5780601f1061209f576101008083540402835291602001916120ca565b820191906000526020600020905b8154815290600101906020018083116120ad57829003601f168201915b5050509183525050600482015460208201526005820154604082015260068201546001600160a01b0316606082015260079091015460809091015292915050565b6121136123b8565b6001600160a01b0381166121785760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108ca565b6111008161292a565b61012f5485906001600160a01b0316632fa117e58261219e6123a9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156121e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220c9190613db1565b6122285760405162461bcd60e51b81526004016108ca90613dce565b6000858152610131602052604090206001810154871461227a5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff16600481111561229257612292613ad4565b146122d75760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b602e83146122f75760405162461bcd60e51b81526004016108ca90613dfd565b806007015485101561234b5760405162461bcd60e51b815260206004820152601c60248201527f43616e27742072656475636520726566657272616c20616d6f756e740000000060448201526064016108ca565b6003810161235a848683613ea2565b50600781018590556040517fae55ce3c351e2400a1a143e7ed66668e581e1656ad1797a317e415d03588091690612398908890879087908a90614227565b60405180910390a150505050505050565b60006123b3612dc9565b905090565b6123c06123a9565b6001600160a01b03166123db6033546001600160a01b031690565b6001600160a01b0316146114ac5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108ca565b61013054604051638a98636360e01b8152600481018890526000916001600160a01b031690638a98636390602401602060405180830381865afa15801561247c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a09190614252565b90508034146124e65760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b602e85146125065760405162461bcd60e51b81526004016108ca90613dfd565b6001600160a01b0382166000908152610135602052604090205460ff166125635760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108ca565b61013054604051631fff7f2760e11b8152600481018990526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa1580156125ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d2919061426b565b90506001600160a01b0381161561262f57600089815261013360209081526040808320549051612609928d92918c918c9101614288565b60405160208183030381529060405280519060200120905061262d86868385612e02565b505b505050505050505050565b611100816126466123a9565b612ef6565b6126558282611583565b61102057600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561268e6123a9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6126dc8282611583565b1561102057600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191690556127136123a9565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6111006123b8565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561279257610f9183612f4f565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156127ec575060408051601f3d908101601f191682019092526127e991810190614252565b60015b61284f5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108ca565b60008051602061443b83398151915281146128be5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108ca565b50610f91838383612feb565b600054610100900460ff166128f15760405162461bcd60e51b81526004016108ca906142c9565b6114ac613016565b600054610100900460ff166114ac5760405162461bcd60e51b81526004016108ca906142c9565b611020828261264b565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61013054604051634a7ab1d560e01b8152600481018890526000916001600160a01b031690634a7ab1d590602401602060405180830381865afa1580156129c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129eb9190614252565b9050803414612a315760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b60008981526101316020908152604080832060068101546001600160a01b03168452610135909252909120600101546007820154612a6f908b614314565b1015612aae5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b6000815460ff166004811115612ac657612ac6613ad4565b14612b085760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b8060010154600003612b505760405162461bcd60e51b815260206004820152601160248201527014d95c9d9a58d9481b9bdd08195e1a5cdd607a1b60448201526064016108ca565b60008a8152610132602090815260408083208e84529091529020600101548b9003612bb65760405162461bcd60e51b81526020600482015260166024820152751c1c9bdc1bdcd85b08185b1c9958591e48195e1a5cdd60521b60448201526064016108ca565b8215612c1c576000816007015411612c1c5760405162461bcd60e51b8152602060048201526024808201527f43616e277420726566657220736f6d656f6e6520666f722074686973207365726044820152637669636560e01b60648201526084016108ca565b8a816001015403612c795760405162461bcd60e51b815260206004820152602160248201527f63616e27742063726561746520666f7220796f7572206f776e207365727669636044820152606560f81b60648201526084016108ca565b602e8614612c995760405162461bcd60e51b81526004016108ca90613dfd565b61013054604051631fff7f2760e11b8152600481018a90526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d08919061426b565b90506001600160a01b03811615612d585760008c8c8a8a604051602001612d329493929190614327565b604051602081830303815290604052805190602001209050612d5687878385612e02565b505b8315612dbb5761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015612da257600080fd5b505afa158015612db6573d6000803e3d6000fd5b505050505b505050505050505050505050565b600060143610801590612deb57503360009081526065602052604090205460ff165b15612dfd575060131936013560601c90565b503390565b6000612e5b836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000612e9f8287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061304d92505050565b9050806001600160a01b0316836001600160a01b031614611b245760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064016108ca565b612f008282611583565b61102057612f0d81613071565b612f18836020613083565b604051602001612f29929190614369565b60408051601f198184030181529082905262461bcd60e51b82526108ca916004016143de565b6001600160a01b0381163b612fbc5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108ca565b60008051602061443b83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b612ff483613226565b6000825111806130015750805b15610f91576130108383613266565b50505050565b600054610100900460ff1661303d5760405162461bcd60e51b81526004016108ca906142c9565b6114ac6130486123a9565b61292a565b600080600061305c858561335a565b915091506130698161339c565b509392505050565b606061081d6001600160a01b03831660145b606060006130928360026141ee565b61309d906002614314565b67ffffffffffffffff8111156130b5576130b56138d2565b6040519080825280601f01601f1916602001820160405280156130df576020820181803683370190505b509050600360fc1b816000815181106130fa576130fa6143f1565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613129576131296143f1565b60200101906001600160f81b031916908160001a905350600061314d8460026141ee565b613158906001614314565b90505b60018111156131d0576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061318c5761318c6143f1565b1a60f81b8282815181106131a2576131a26143f1565b60200101906001600160f81b031916908160001a90535060049490941c936131c981614407565b905061315b565b50831561321f5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108ca565b9392505050565b61322f81612f4f565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6132ce5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108ca565b600080846001600160a01b0316846040516132e9919061441e565b600060405180830381855af49150503d8060008114613324576040519150601f19603f3d011682016040523d82523d6000602084013e613329565b606091505b5091509150613351828260405180606001604052806027815260200161445b602791396134e6565b95945050505050565b60008082516041036133905760208301516040840151606085015160001a613384878285856134ff565b94509450505050611f5f565b50600090506002611f5f565b60008160048111156133b0576133b0613ad4565b036133b85750565b60018160048111156133cc576133cc613ad4565b036134195760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108ca565b600281600481111561342d5761342d613ad4565b0361347a5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108ca565b600381600481111561348e5761348e613ad4565b036111005760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108ca565b606083156134f557508161321f565b61321f83836135c3565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561353657506000905060036135ba565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561358a573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166135b3576000600192509250506135ba565b9150600090505b94509492505050565b8151156135d35781518083602001fd5b8060405162461bcd60e51b81526004016108ca91906143de565b60408051610100810190915280600081526020016000815260200160006001600160a01b0316815260200160008152602001600081526020016060815260200160008152602001600081525090565b6040805161010081019091528060008152602001600081526020016000815260200160608152602001600081526020016000815260200160006001600160a01b03168152602001600081525090565b60006020828403121561369d57600080fd5b81356001600160e01b03198116811461321f57600080fd5b600080604083850312156136c857600080fd5b50508035926020909101359150565b60008083601f8401126136e957600080fd5b50813567ffffffffffffffff81111561370157600080fd5b602083019150836020828501011115611f5f57600080fd5b600080600080600080600060c0888a03121561373457600080fd5b873596506020880135955060408801359450606088013567ffffffffffffffff81111561376057600080fd5b61376c8a828b016136d7565b989b979a50959895979660808701359660a0013595509350505050565b60006020828403121561379b57600080fd5b5035919050565b6001600160a01b038116811461110057600080fd5b6000602082840312156137c957600080fd5b813561321f816137a2565b60008060008060008060008060c0898b0312156137f057600080fd5b8835975060208901359650604089013567ffffffffffffffff8082111561381657600080fd5b6138228c838d016136d7565b909850965060608b013591508082111561383b57600080fd5b506138488b828c016136d7565b909550935050608089013561385c816137a2565b8092505060a089013590509295985092959890939650565b6000806040838503121561388757600080fd5b823591506020830135613899816137a2565b809150509250929050565b600080604083850312156138b757600080fd5b82356138c2816137a2565b91506020830135613899816137a2565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156138fb57600080fd5b8235613906816137a2565b9150602083013567ffffffffffffffff8082111561392357600080fd5b818501915085601f83011261393757600080fd5b813581811115613949576139496138d2565b604051601f8201601f19908116603f01168101908382118183101715613971576139716138d2565b8160405282815288602084870101111561398a57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b801515811461110057600080fd5b6000806000606084860312156139cf57600080fd5b83356139da816137a2565b925060208401356139ea816139ac565b929592945050506040919091013590565b6000806000806000806000806000806101008b8d031215613a1b57600080fd5b8a35995060208b0135985060408b0135975060608b0135965060808b013567ffffffffffffffff80821115613a4f57600080fd5b613a5b8e838f016136d7565b909850965060a08d0135955060c08d0135915080821115613a7b57600080fd5b50613a888d828e016136d7565b9150809450508092505060e08b013590509295989b9194979a5092959850565b600080600060608486031215613abd57600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052602160045260246000fd5b60028110613afa57613afa613ad4565b9052565b60005b83811015613b19578181015183820152602001613b01565b50506000910152565b60008151808452613b3a816020860160208601613afe565b601f01601f19169290920160200192915050565b6000610100613b5e848451613aea565b6020830151602085015260018060a01b036040840151166040850152606083015160608501526080830151608085015260a08301518160a0860152613ba582860182613b22565b91505060c083015160c085015260e083015160e08501528091505092915050565b60208152600061321f6020830184613b4e565b60058110613afa57613afa613ad4565b6000610100613bf8838c613bd9565b896020840152886040840152806060840152613c1681840189613b22565b6080840197909752505060a08101939093526001600160a01b039190911660c083015260e090910152949350505050565b6000610100613c56838c613aea565b89602084015260018060a01b03891660408401528760608401528660808401528060a0840152613c8881840187613b22565b60c0840195909552505060e001529695505050505050565b6000610100613cb0848451613bd9565b60208301516020850152604083015160408501526060830151816060860152613cdb82860182613b22565b6080858101519087015260a0808601519087015260c0808601516001600160a01b03169087015260e0948501519490950193909352509192915050565b604081526000613d2b6040830185613ca0565b82810360208401526133518185613b4e565b60208152600061321f6020830184613ca0565b600080600080600060808688031215613d6857600080fd5b853594506020860135935060408601359250606086013567ffffffffffffffff811115613d9457600080fd5b613da0888289016136d7565b969995985093965092949392505050565b600060208284031215613dc357600080fd5b815161321f816139ac565b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b6020808252600b908201526a125b9d985b1a590818da5960aa1b604082015260600190565b600181811c90821680613e3657607f821691505b602082108103613e5657634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610f9157600081815260208120601f850160051c81016020861015613e835750805b601f850160051c820191505b81811015611b2457828155600101613e8f565b67ffffffffffffffff831115613eba57613eba6138d2565b613ece83613ec88354613e22565b83613e5c565b6000601f841160018114613f025760008515613eea5750838201355b600019600387901b1c1916600186901b178355613f5c565b600083815260209020601f19861690835b82811015613f335786850135825560209485019460019092019101613f13565b5086821015613f505760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b87815286602082015260c060408201526000613fac60c083018789613f63565b606083019590955250608081019290925260a090910152949350505050565b634e487b7160e01b600052601160045260246000fd5b600060018201613ff357613ff3613fcb565b5060010190565b87815286602082015285604082015260c06060820152600061402060c083018688613f63565b6001600160a01b039490941660808301525060a0015295945050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b815167ffffffffffffffff8111156140f1576140f16138d2565b614105816140ff8454613e22565b84613e5c565b602080601f83116001811461413a57600084156141225750858301515b600019600386901b1c1916600185901b178555611b24565b600085815260208120601f198616915b828110156141695788860151825594840194600190910190840161414a565b50858210156141875787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006101008b83528a60208401528060408401526141b88184018a8c613f63565b9150506141c86060830188613aea565b8560808301528460a08301528360c08301528260e08301529a9950505050505050505050565b808202811582820484141761081d5761081d613fcb565b60008261422257634e487b7160e01b600052601260045260246000fd5b500490565b848152606060208201526000614241606083018587613f63565b905082604083015295945050505050565b60006020828403121561426457600080fd5b5051919050565b60006020828403121561427d57600080fd5b815161321f816137a2565b6c6372656174655365727669636560981b815284600d820152603b60f81b602d82015283602e8201528183604e83013760009101604e019081529392505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8082018082111561081d5761081d613fcb565b6d18dc99585d19541c9bdc1bdcd85b60921b815284600e820152603b60f81b602e82015283602f8201528183604f83013760009101604f019081529392505050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516143a1816017850160208801613afe565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516143d2816028840160208801613afe565b01602801949350505050565b60208152600061321f6020830184613b22565b634e487b7160e01b600052603260045260246000fd5b60008161441657614416613fcb565b506000190190565b60008251614430818460208701613afe565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220397b6e8ab583d064618d0d5b7fe3da4cfb56beab325a99d1a0fca57da22eb57e64736f6c63430008110033", + "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6080516144ec62000120600039600081816112d301528181611313015281816115ca0152818161160a015261169901526144ec6000f3fe6080604052600436106102305760003560e01c80636ce76f301161012e578063b5735c1e116100ab578063d547741f1161006f578063d547741f1461072e578063ef0e239b1461074e578063f2fde38b1461077b578063f6c53d9b1461079b578063f9eaee0d146107b257600080fd5b8063b5735c1e1461064a578063c22c4f431461066a578063c2cfee271461069e578063ccaa7d2a146106d2578063d4eee1fc1461070057600080fd5b806391d14854116100f257806391d14854146105b5578063a217fddf146105d5578063a24bd889146105ea578063a7d5eaea146105fd578063aba210091461061d57600080fd5b80636ce76f30146104dc578063715018a61461051057806371da85f9146105255780637c5a72cd146105775780638da5cb5b1461059757600080fd5b80632afaf220116101bc5780633ca2ad6f116101805780633ca2ad6f1461043b578063485cc9551461045b5780634f1ef2861461047b57806352d1902d1461048e578063572b6c05146104a357600080fd5b80632afaf220146103a85780632f2ff15d146103bb57806336568abe146103db5780633659cfe6146103fb5780633751d89c1461041b57600080fd5b8063156b39aa11610203578063156b39aa146102e557806319de9d6c1461030a5780631db087ff1461032a578063248a9ca31461035857806326d006681461038857600080fd5b806301ffc9a714610235578063089b7c731461026a5780631499f9e61461028c578063154664ed146102c5575b600080fd5b34801561024157600080fd5b506102556102503660046136a2565b6107ec565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061028a6102853660046136cc565b610823565b005b34801561029857600080fd5b50610130546102ad906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b3480156102d157600080fd5b5061028a6102e0366004613730565b6109c6565b3480156102f157600080fd5b506102fc6101365481565b604051908152602001610261565b34801561031657600080fd5b5061028a6103253660046137b5565b610cde565b34801561033657600080fd5b506102fc610345366004613828565b6101336020526000908152604090205481565b34801561036457600080fd5b506102fc610373366004613828565b600090815260fc602052604090206001015490565b34801561039457600080fd5b5061028a6103a3366004613841565b610f83565b6102fc6103b636600461385e565b610fe6565b3480156103c757600080fd5b5061028a6103d63660046138fe565b611211565b3480156103e757600080fd5b5061028a6103f63660046138fe565b61123b565b34801561040757600080fd5b5061028a610416366004613841565b6112c9565b34801561042757600080fd5b5061028a610436366004613841565b6113a8565b34801561044757600080fd5b5061028a610456366004613828565b611401565b34801561046757600080fd5b5061028a61047636600461392e565b611449565b61028a610489366004613972565b6115c0565b34801561049a57600080fd5b506102fc61168c565b3480156104af57600080fd5b506102556104be366004613841565b6001600160a01b031660009081526065602052604090205460ff1690565b3480156104e857600080fd5b506102fc7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f81565b34801561051c57600080fd5b5061028a61173f565b34801561053157600080fd5b50610560610540366004613841565b610135602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610261565b34801561058357600080fd5b5061028a610592366004613a44565b611753565b3480156105a357600080fd5b506033546001600160a01b03166102ad565b3480156105c157600080fd5b506102556105d03660046138fe565b611828565b3480156105e157600080fd5b506102fc600081565b61028a6105f8366004613a85565b611853565b34801561060957600080fd5b5061028a610618366004613b32565b611b6d565b34801561062957600080fd5b5061063d6106383660046136cc565b611bef565b6040516102619190613c50565b34801561065657600080fd5b5061028a6106653660046136cc565b611d2c565b34801561067657600080fd5b5061068a610685366004613828565b611dd1565b604051610261989796959493929190613c73565b3480156106aa57600080fd5b506106be6106b93660046136cc565b611eae565b604051610261989796959493929190613cd1565b3480156106de57600080fd5b506102fc6106ed366004613828565b6101346020526000908152604090205481565b34801561070c57600080fd5b5061072061071b3660046136cc565b611f95565b604051610261929190613da2565b34801561073a57600080fd5b5061028a6107493660046138fe565b61220b565b34801561075a57600080fd5b5061076e610769366004613828565b612230565b6040516102619190613dc7565b34801561078757600080fd5b5061028a610796366004613841565b6123b0565b3480156107a757600080fd5b506102fc61012e5481565b3480156107be57600080fd5b506102556107cd366004613841565b6001600160a01b03166000908152610135602052604090205460ff1690565b60006001600160e01b03198216637965db0b60e01b148061081d57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61012f5482906001600160a01b0316632fa117e582610840612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561088a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ae9190613dda565b6108d35760405162461bcd60e51b81526004016108ca90613df7565b60405180910390fd5b600082815261013160205260409020600181015484146109255760405162461bcd60e51b815260206004820152600d60248201526c3737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff16600481111561093d5761093d613b5e565b146109825760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b805460ff191660031781556040518381527f853aa4be1ac86f37acfc91d42b57f1fe895205aa6f8f9b7caa77ca257049ab1a9060200160405180910390a150505050565b61012f5487906001600160a01b0316632fa117e5826109e3612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a519190613dda565b610a6d5760405162461bcd60e51b81526004016108ca90613df7565b60008781526101316020908152604080832061013283528184208c855290925282209091825460ff166004811115610aa757610aa7613b5e565b14610ae95760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b89816001015414610b2c5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b602e8614610b4c5760405162461bcd60e51b81526004016108ca90613e26565b6001815460ff166001811115610b6457610b64613b5e565b03610ba55760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481d985b1a59185d1959607a1b60448201526064016108ca565b60068201546001600160a01b031660009081526101356020526040902060010154881015610c065760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b8315610c695761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015610c5057600080fd5b505afa158015610c64573d6000803e3d6000fd5b505050505b6003810188905560058101610c7f878983613ecb565b5060068101859055600781018490556040517ffbfaa6f4e508bec40137ac265a7424e16a2d209355b2f4a35de5a80ba8fec1db90610cca908b908d908b908b908e908c908c90613fb5565b60405180910390a150505050505050505050565b61012f5486906001600160a01b0316632fa117e582610cfb612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610d45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d699190613dda565b610d855760405162461bcd60e51b81526004016108ca90613df7565b60008681526101316020526040902060018101548814610dd75760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff166004811115610def57610def613b5e565b14610e345760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b602e8314610e545760405162461bcd60e51b81526004016108ca90613e26565b6001600160a01b0386166000908152610135602052604090205460ff16610eb15760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108ca565b8060070154851015610f055760405162461bcd60e51b815260206004820152601c60248201527f43616e27742072656475636520726566657272616c20616d6f756e740000000060448201526064016108ca565b60038101610f14848683613ecb565b50600781018590556006810180546001600160a01b0319166001600160a01b0388161790556040517f79dba2b7507f91f38c9a67e52f174c234541b20eccc91ad6afe9d3753f6371f590610f71908990879087908b908b90613ff4565b60405180910390a15050505050505050565b610f8b612435565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b61012f5460009089906001600160a01b0316632fa117e582611006612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611050573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110749190613dda565b6110905760405162461bcd60e51b81526004016108ca90613df7565b61109f8a8a8a8a8a8a8a6124ae565b61012e805490819060006110b283614041565b9091555050600081815261013160205260409020805460ff19168155600181018c9055600381016110e48a8c83613ecb565b50600581018b90556006810180546001600160a01b0319166001600160a01b0388161790556007810185905560008c8152610133602052604090205415801561113a575060008c81526101346020526040902054155b1561119f5761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b15801561118657600080fd5b505af115801561119a573d6000803e3d6000fd5b505050505b60008c8152610133602052604081208054916111ba83614041565b91905055507fe7f6435fc92b0ccd6f56395ae67b06f2cdb9680c0179f87f5821431304ad3f3e828d8d8d8d8b8b6040516111fa979695949392919061405a565b60405180910390a1509a9950505050505050505050565b600082815260fc602052604090206001015461122c816126b7565b61123683836126c8565b505050565b611243612426565b6001600160a01b0316816001600160a01b0316146112bb5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108ca565b6112c5828261274f565b5050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036113115760405162461bcd60e51b81526004016108ca9061409f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661135a600080516020614470833981519152546001600160a01b031690565b6001600160a01b0316146113805760405162461bcd60e51b81526004016108ca906140eb565b611389816127d4565b604080516000808252602082019092526113a5918391906127dc565b50565b6113b0612435565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee69101610fdb565b600061140c816126b7565b6101368290556040518281527f577d7afcf67637a2f602cba220bbb292c1d715380dd011bfec748c3f641b2fd29060200160405180910390a15050565b600054610100900460ff16158080156114695750600054600160ff909116105b806114835750303b158015611483575060005460ff166001145b6114e65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108ca565b6000805460ff191660011790558015611509576000805461ff0019166101001790555b611511612947565b611519612976565b611521612976565b611533600061152e612426565b61299d565b61012f80546001600160a01b038086166001600160a01b031992831617909255610130805492851692909116919091179055600161012e55611575601e611401565b8015611236576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036116085760405162461bcd60e51b81526004016108ca9061409f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611651600080516020614470833981519152546001600160a01b031690565b6001600160a01b0316146116775760405162461bcd60e51b81526004016108ca906140eb565b611680826127d4565b6112c5828260016127dc565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461172c5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108ca565b5060008051602061447083398151915290565b611747612435565b61175160006129a7565b565b61175b612435565b6001600160a01b038316158015611770575081155b156117bd5760405162461bcd60e51b815260206004820152601d60248201527f4f776e65722063616e27742072656d6f7665204f78206164647265737300000060448201526064016108ca565b6001600160a01b03831660008181526101356020908152604091829020805460ff19168615159081178255600190910185905582519384529083015281018290527f42b585a1da1cff4b571e7a78aea1b4601b1d128de41a0feebd8a77aaf48b9d88906060016115b3565b600091825260fc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61012f548a906001600160a01b0316632fa117e582611870612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156118ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118de9190613dda565b6118fa5760405162461bcd60e51b81526004016108ca90613df7565b60008a81526101316020526040902061191a8c8c8c8c8c8c8b8b8b6129f9565b60408051610100810182526000815260208082018f905260068401546001600160a01b031682840152606082018d9052608082018c90528251601f8b01829004820281018201909352898352909160a08301918b908b9081908401838280828437600081840152601f19601f8201169050808301925050505050505081526020018781526020018481525061013260008d815260200190815260200160002060008e815260200190815260200160002060008201518160000160006101000a81548160ff021916908360018111156119f4576119f4613b5e565b02179055506020820151600182015560408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a08201516005820190611a519082614137565b5060c0820151600682015560e09091015160079091015560008c81526101336020526040902054158015611a92575060008c81526101346020526040902054155b15611af75761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015611ade57600080fd5b505af1158015611af2573d6000803e3d6000fd5b505050505b60008c815261013460205260408120805491611b1283614041565b91905055507fabd26455c3256ad90125661f4c1a4c16fecf585ccade21e749c56d8fd44bb1dd8b8d8a8a60008f8f8d8b604051611b57999897969594939291906141f7565b60405180910390a1505050505050505050505050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611b97816126b7565b60008481526101316020908152604080832061013283528184208785529092529091208154600160ff1991821681178455808301546002850155600484018690558254909183911682805b0217905550505050505050565b611bf7613604565b60008381526101326020908152604080832085845290915290819020815161010081019092528054829060ff166001811115611c3557611c35613b5e565b6001811115611c4657611c46613b5e565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611c8e90613e4b565b80601f0160208091040260200160405190810160405280929190818152602001828054611cba90613e4b565b8015611d075780601f10611cdc57610100808354040283529160200191611d07565b820191906000526020600020905b815481529060010190602001808311611cea57829003601f168201915b5050505050815260200160068201548152602001600782015481525050905092915050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611d56816126b7565b6000838152610131602090815260408083206101328352818420600282015485529092528220600381015491929091611d9086606461424e565b611d9a9190614265565b9050610136548110611db657825460ff19166002178355611dc9565b8254600490849060ff1916600183611be2565b505050505050565b61013160205260009081526040902080546001820154600283015460038401805460ff909416949293919291611e0690613e4b565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3290613e4b565b8015611e7f5780601f10611e5457610100808354040283529160200191611e7f565b820191906000526020600020905b815481529060010190602001808311611e6257829003601f168201915b505050600484015460058501546006860154600790960154949591949093506001600160a01b03909116915088565b61013260209081526000928352604080842090915290825290208054600182015460028301546003840154600485015460058601805460ff9096169694956001600160a01b03909416949293919291611f0690613e4b565b80601f0160208091040260200160405190810160405280929190818152602001828054611f3290613e4b565b8015611f7f5780601f10611f5457610100808354040283529160200191611f7f565b820191906000526020600020905b815481529060010190602001808311611f6257829003601f168201915b5050505050908060060154908060070154905088565b611f9d613653565b611fa5613604565b60008481526101316020526040808220815161010081019092528054829060ff166004811115611fd757611fd7613b5e565b6004811115611fe857611fe8613b5e565b8152602001600182015481526020016002820154815260200160038201805461201090613e4b565b80601f016020809104026020016040519081016040528092919081815260200182805461203c90613e4b565b80156120895780601f1061205e57610100808354040283529160200191612089565b820191906000526020600020905b81548152906001019060200180831161206c57829003601f168201915b50505091835250506004820154602080830191909152600583015460408084019190915260068401546001600160a01b03166060840152600790930154608090920191909152600088815261013282528281208882529091528181208251610100810190935280549394509092829060ff16600181111561210c5761210c613b5e565b600181111561211d5761211d613b5e565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a09092019161216590613e4b565b80601f016020809104026020016040519081016040528092919081815260200182805461219190613e4b565b80156121de5780601f106121b3576101008083540402835291602001916121de565b820191906000526020600020905b8154815290600101906020018083116121c157829003601f168201915b505050918352505060068201546020820152600790910154604090910152919350909150505b9250929050565b600082815260fc6020526040902060010154612226816126b7565b611236838361274f565b612238613653565b61012e54821061228a5760405162461bcd60e51b815260206004820152601a60248201527f54686973207365727669636520646f65736e277420657869737400000000000060448201526064016108ca565b6000828152610131602052604090819020815161010081019092528054829060ff1660048111156122bd576122bd613b5e565b60048111156122ce576122ce613b5e565b815260200160018201548152602001600282015481526020016003820180546122f690613e4b565b80601f016020809104026020016040519081016040528092919081815260200182805461232290613e4b565b801561236f5780601f106123445761010080835404028352916020019161236f565b820191906000526020600020905b81548152906001019060200180831161235257829003601f168201915b5050509183525050600482015460208201526005820154604082015260068201546001600160a01b0316606082015260079091015460809091015292915050565b6123b8612435565b6001600160a01b03811661241d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108ca565b6113a5816129a7565b6000612430612de0565b905090565b61243d612426565b6001600160a01b03166124586033546001600160a01b031690565b6001600160a01b0316146117515760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108ca565b61013054604051638a98636360e01b8152600481018890526000916001600160a01b031690638a98636390602401602060405180830381865afa1580156124f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061251d9190614287565b90508034146125635760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b602e85146125835760405162461bcd60e51b81526004016108ca90613e26565b6001600160a01b0382166000908152610135602052604090205460ff166125e05760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108ca565b61013054604051631fff7f2760e11b8152600481018990526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa15801561262b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264f91906142a0565b90506001600160a01b038116156126ac57600089815261013360209081526040808320549051612686928d92918c918c91016142bd565b6040516020818303038152906040528051906020012090506126aa86868385612e19565b505b505050505050505050565b6113a5816126c3612426565b612f0d565b6126d28282611828565b6112c557600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561270b612426565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6127598282611828565b156112c557600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff19169055612790612426565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6113a5612435565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561280f5761123683612f66565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612869575060408051601f3d908101601f1916820190925261286691810190614287565b60015b6128cc5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108ca565b600080516020614470833981519152811461293b5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108ca565b50611236838383613002565b600054610100900460ff1661296e5760405162461bcd60e51b81526004016108ca906142fe565b61175161302d565b600054610100900460ff166117515760405162461bcd60e51b81526004016108ca906142fe565b6112c582826126c8565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61013054604051634a7ab1d560e01b8152600481018890526000916001600160a01b031690634a7ab1d590602401602060405180830381865afa158015612a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a689190614287565b9050803414612aae5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b60008981526101316020908152604080832060068101546001600160a01b03168452610135909252909120600101546007820154612aec908b614349565b1015612b2b5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b6000815460ff166004811115612b4357612b43613b5e565b14612b855760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b8060010154600003612bcd5760405162461bcd60e51b815260206004820152601160248201527014d95c9d9a58d9481b9bdd08195e1a5cdd607a1b60448201526064016108ca565b60008a8152610132602090815260408083208e84529091529020600101548b9003612c335760405162461bcd60e51b81526020600482015260166024820152751c1c9bdc1bdcd85b08185b1c9958591e48195e1a5cdd60521b60448201526064016108ca565b8a816001015403612c905760405162461bcd60e51b815260206004820152602160248201527f63616e27742063726561746520666f7220796f7572206f776e207365727669636044820152606560f81b60648201526084016108ca565b602e8614612cb05760405162461bcd60e51b81526004016108ca90613e26565b61013054604051631fff7f2760e11b8152600481018a90526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612cfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d1f91906142a0565b90506001600160a01b03811615612d6f5760008c8c8a8a604051602001612d49949392919061435c565b604051602081830303815290604052805190602001209050612d6d87878385612e19565b505b8315612dd25761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015612db957600080fd5b505afa158015612dcd573d6000803e3d6000fd5b505050505b505050505050505050505050565b600060143610801590612e0257503360009081526065602052604090205460ff165b15612e14575060131936013560601c90565b503390565b6000612e72836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000612eb68287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061306492505050565b9050806001600160a01b0316836001600160a01b031614611dc95760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064016108ca565b612f178282611828565b6112c557612f2481613088565b612f2f83602061309a565b604051602001612f4092919061439e565b60408051601f198184030181529082905262461bcd60e51b82526108ca91600401614413565b6001600160a01b0381163b612fd35760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108ca565b60008051602061447083398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61300b8361323d565b6000825111806130185750805b1561123657613027838361327d565b50505050565b600054610100900460ff166130545760405162461bcd60e51b81526004016108ca906142fe565b61175161305f612426565b6129a7565b60008060006130738585613371565b91509150613080816133b3565b509392505050565b606061081d6001600160a01b03831660145b606060006130a983600261424e565b6130b4906002614349565b67ffffffffffffffff8111156130cc576130cc61395c565b6040519080825280601f01601f1916602001820160405280156130f6576020820181803683370190505b509050600360fc1b8160008151811061311157613111614426565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061314057613140614426565b60200101906001600160f81b031916908160001a905350600061316484600261424e565b61316f906001614349565b90505b60018111156131e7576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106131a3576131a3614426565b1a60f81b8282815181106131b9576131b9614426565b60200101906001600160f81b031916908160001a90535060049490941c936131e08161443c565b9050613172565b5083156132365760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108ca565b9392505050565b61324681612f66565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6132e55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108ca565b600080846001600160a01b0316846040516133009190614453565b600060405180830381855af49150503d806000811461333b576040519150601f19603f3d011682016040523d82523d6000602084013e613340565b606091505b50915091506133688282604051806060016040528060278152602001614490602791396134fd565b95945050505050565b60008082516041036133a75760208301516040840151606085015160001a61339b87828585613516565b94509450505050612204565b50600090506002612204565b60008160048111156133c7576133c7613b5e565b036133cf5750565b60018160048111156133e3576133e3613b5e565b036134305760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108ca565b600281600481111561344457613444613b5e565b036134915760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108ca565b60038160048111156134a5576134a5613b5e565b036113a55760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108ca565b6060831561350c575081613236565b61323683836135da565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561354d57506000905060036135d1565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156135a1573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166135ca576000600192509250506135d1565b9150600090505b94509492505050565b8151156135ea5781518083602001fd5b8060405162461bcd60e51b81526004016108ca9190614413565b60408051610100810190915280600081526020016000815260200160006001600160a01b0316815260200160008152602001600081526020016060815260200160008152602001600081525090565b6040805161010081019091528060008152602001600081526020016000815260200160608152602001600081526020016000815260200160006001600160a01b03168152602001600081525090565b6000602082840312156136b457600080fd5b81356001600160e01b03198116811461323657600080fd5b600080604083850312156136df57600080fd5b50508035926020909101359150565b60008083601f84011261370057600080fd5b50813567ffffffffffffffff81111561371857600080fd5b60208301915083602082850101111561220457600080fd5b600080600080600080600060c0888a03121561374b57600080fd5b873596506020880135955060408801359450606088013567ffffffffffffffff81111561377757600080fd5b6137838a828b016136ee565b989b979a50959895979660808701359660a0013595509350505050565b6001600160a01b03811681146113a557600080fd5b60008060008060008060a087890312156137ce57600080fd5b863595506020870135945060408701356137e7816137a0565b935060608701359250608087013567ffffffffffffffff81111561380a57600080fd5b61381689828a016136ee565b979a9699509497509295939492505050565b60006020828403121561383a57600080fd5b5035919050565b60006020828403121561385357600080fd5b8135613236816137a0565b60008060008060008060008060c0898b03121561387a57600080fd5b8835975060208901359650604089013567ffffffffffffffff808211156138a057600080fd5b6138ac8c838d016136ee565b909850965060608b01359150808211156138c557600080fd5b506138d28b828c016136ee565b90955093505060808901356138e6816137a0565b8092505060a089013590509295985092959890939650565b6000806040838503121561391157600080fd5b823591506020830135613923816137a0565b809150509250929050565b6000806040838503121561394157600080fd5b823561394c816137a0565b91506020830135613923816137a0565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561398557600080fd5b8235613990816137a0565b9150602083013567ffffffffffffffff808211156139ad57600080fd5b818501915085601f8301126139c157600080fd5b8135818111156139d3576139d361395c565b604051601f8201601f19908116603f011681019083821181831017156139fb576139fb61395c565b81604052828152886020848701011115613a1457600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b80151581146113a557600080fd5b600080600060608486031215613a5957600080fd5b8335613a64816137a0565b92506020840135613a7481613a36565b929592945050506040919091013590565b6000806000806000806000806000806101008b8d031215613aa557600080fd5b8a35995060208b0135985060408b0135975060608b0135965060808b013567ffffffffffffffff80821115613ad957600080fd5b613ae58e838f016136ee565b909850965060a08d0135955060c08d0135915080821115613b0557600080fd5b50613b128d828e016136ee565b9150809450508092505060e08b013590509295989b9194979a5092959850565b600080600060608486031215613b4757600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052602160045260246000fd5b60028110613b8457613b84613b5e565b9052565b60005b83811015613ba3578181015183820152602001613b8b565b50506000910152565b60008151808452613bc4816020860160208601613b88565b601f01601f19169290920160200192915050565b6000610100613be8848451613b74565b6020830151602085015260018060a01b036040840151166040850152606083015160608501526080830151608085015260a08301518160a0860152613c2f82860182613bac565b91505060c083015160c085015260e083015160e08501528091505092915050565b6020815260006132366020830184613bd8565b60058110613b8457613b84613b5e565b6000610100613c82838c613c63565b896020840152886040840152806060840152613ca081840189613bac565b6080840197909752505060a08101939093526001600160a01b039190911660c083015260e090910152949350505050565b6000610100613ce0838c613b74565b89602084015260018060a01b03891660408401528760608401528660808401528060a0840152613d1281840187613bac565b60c0840195909552505060e001529695505050505050565b6000610100613d3a848451613c63565b60208301516020850152604083015160408501526060830151816060860152613d6582860182613bac565b6080858101519087015260a0808601519087015260c0808601516001600160a01b03169087015260e0948501519490950193909352509192915050565b604081526000613db56040830185613d2a565b82810360208401526133688185613bd8565b6020815260006132366020830184613d2a565b600060208284031215613dec57600080fd5b815161323681613a36565b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b6020808252600b908201526a125b9d985b1a590818da5960aa1b604082015260600190565b600181811c90821680613e5f57607f821691505b602082108103613e7f57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561123657600081815260208120601f850160051c81016020861015613eac5750805b601f850160051c820191505b81811015611dc957828155600101613eb8565b67ffffffffffffffff831115613ee357613ee361395c565b613ef783613ef18354613e4b565b83613e85565b6000601f841160018114613f2b5760008515613f135750838201355b600019600387901b1c1916600186901b178355613f85565b600083815260209020601f19861690835b82811015613f5c5786850135825560209485019460019092019101613f3c565b5086821015613f795760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b87815286602082015260c060408201526000613fd560c083018789613f8c565b606083019590955250608081019290925260a090910152949350505050565b85815260806020820152600061400e608083018688613f8c565b6001600160a01b0394909416604083015250606001529392505050565b634e487b7160e01b600052601160045260246000fd5b6000600182016140535761405361402b565b5060010190565b87815286602082015285604082015260c06060820152600061408060c083018688613f8c565b6001600160a01b039490941660808301525060a0015295945050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b815167ffffffffffffffff8111156141515761415161395c565b6141658161415f8454613e4b565b84613e85565b602080601f83116001811461419a57600084156141825750858301515b600019600386901b1c1916600185901b178555611dc9565b600085815260208120601f198616915b828110156141c9578886015182559484019460019091019084016141aa565b50858210156141e75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006101008b83528a60208401528060408401526142188184018a8c613f8c565b9150506142286060830188613b74565b8560808301528460a08301528360c08301528260e08301529a9950505050505050505050565b808202811582820484141761081d5761081d61402b565b60008261428257634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561429957600080fd5b5051919050565b6000602082840312156142b257600080fd5b8151613236816137a0565b6c6372656174655365727669636560981b815284600d820152603b60f81b602d82015283602e8201528183604e83013760009101604e019081529392505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8082018082111561081d5761081d61402b565b6d18dc99585d19541c9bdc1bdcd85b60921b815284600e820152603b60f81b602e82015283602f8201528183604f83013760009101604f019081529392505050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516143d6816017850160208801613b88565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351614407816028840160208801613b88565b01602801949350505050565b6020815260006132366020830184613bac565b634e487b7160e01b600052603260045260246000fd5b60008161444b5761444b61402b565b506000190190565b60008251614465818460208701613b88565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a1ba7d9ed8bda0e85592c39f8b8a90f379bcd674d0b9fd980896e2501b6dde2264736f6c63430008110033", + "deployedBytecode": "0x6080604052600436106102305760003560e01c80636ce76f301161012e578063b5735c1e116100ab578063d547741f1161006f578063d547741f1461072e578063ef0e239b1461074e578063f2fde38b1461077b578063f6c53d9b1461079b578063f9eaee0d146107b257600080fd5b8063b5735c1e1461064a578063c22c4f431461066a578063c2cfee271461069e578063ccaa7d2a146106d2578063d4eee1fc1461070057600080fd5b806391d14854116100f257806391d14854146105b5578063a217fddf146105d5578063a24bd889146105ea578063a7d5eaea146105fd578063aba210091461061d57600080fd5b80636ce76f30146104dc578063715018a61461051057806371da85f9146105255780637c5a72cd146105775780638da5cb5b1461059757600080fd5b80632afaf220116101bc5780633ca2ad6f116101805780633ca2ad6f1461043b578063485cc9551461045b5780634f1ef2861461047b57806352d1902d1461048e578063572b6c05146104a357600080fd5b80632afaf220146103a85780632f2ff15d146103bb57806336568abe146103db5780633659cfe6146103fb5780633751d89c1461041b57600080fd5b8063156b39aa11610203578063156b39aa146102e557806319de9d6c1461030a5780631db087ff1461032a578063248a9ca31461035857806326d006681461038857600080fd5b806301ffc9a714610235578063089b7c731461026a5780631499f9e61461028c578063154664ed146102c5575b600080fd5b34801561024157600080fd5b506102556102503660046136a2565b6107ec565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061028a6102853660046136cc565b610823565b005b34801561029857600080fd5b50610130546102ad906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b3480156102d157600080fd5b5061028a6102e0366004613730565b6109c6565b3480156102f157600080fd5b506102fc6101365481565b604051908152602001610261565b34801561031657600080fd5b5061028a6103253660046137b5565b610cde565b34801561033657600080fd5b506102fc610345366004613828565b6101336020526000908152604090205481565b34801561036457600080fd5b506102fc610373366004613828565b600090815260fc602052604090206001015490565b34801561039457600080fd5b5061028a6103a3366004613841565b610f83565b6102fc6103b636600461385e565b610fe6565b3480156103c757600080fd5b5061028a6103d63660046138fe565b611211565b3480156103e757600080fd5b5061028a6103f63660046138fe565b61123b565b34801561040757600080fd5b5061028a610416366004613841565b6112c9565b34801561042757600080fd5b5061028a610436366004613841565b6113a8565b34801561044757600080fd5b5061028a610456366004613828565b611401565b34801561046757600080fd5b5061028a61047636600461392e565b611449565b61028a610489366004613972565b6115c0565b34801561049a57600080fd5b506102fc61168c565b3480156104af57600080fd5b506102556104be366004613841565b6001600160a01b031660009081526065602052604090205460ff1690565b3480156104e857600080fd5b506102fc7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f81565b34801561051c57600080fd5b5061028a61173f565b34801561053157600080fd5b50610560610540366004613841565b610135602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610261565b34801561058357600080fd5b5061028a610592366004613a44565b611753565b3480156105a357600080fd5b506033546001600160a01b03166102ad565b3480156105c157600080fd5b506102556105d03660046138fe565b611828565b3480156105e157600080fd5b506102fc600081565b61028a6105f8366004613a85565b611853565b34801561060957600080fd5b5061028a610618366004613b32565b611b6d565b34801561062957600080fd5b5061063d6106383660046136cc565b611bef565b6040516102619190613c50565b34801561065657600080fd5b5061028a6106653660046136cc565b611d2c565b34801561067657600080fd5b5061068a610685366004613828565b611dd1565b604051610261989796959493929190613c73565b3480156106aa57600080fd5b506106be6106b93660046136cc565b611eae565b604051610261989796959493929190613cd1565b3480156106de57600080fd5b506102fc6106ed366004613828565b6101346020526000908152604090205481565b34801561070c57600080fd5b5061072061071b3660046136cc565b611f95565b604051610261929190613da2565b34801561073a57600080fd5b5061028a6107493660046138fe565b61220b565b34801561075a57600080fd5b5061076e610769366004613828565b612230565b6040516102619190613dc7565b34801561078757600080fd5b5061028a610796366004613841565b6123b0565b3480156107a757600080fd5b506102fc61012e5481565b3480156107be57600080fd5b506102556107cd366004613841565b6001600160a01b03166000908152610135602052604090205460ff1690565b60006001600160e01b03198216637965db0b60e01b148061081d57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61012f5482906001600160a01b0316632fa117e582610840612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561088a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ae9190613dda565b6108d35760405162461bcd60e51b81526004016108ca90613df7565b60405180910390fd5b600082815261013160205260409020600181015484146109255760405162461bcd60e51b815260206004820152600d60248201526c3737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff16600481111561093d5761093d613b5e565b146109825760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b805460ff191660031781556040518381527f853aa4be1ac86f37acfc91d42b57f1fe895205aa6f8f9b7caa77ca257049ab1a9060200160405180910390a150505050565b61012f5487906001600160a01b0316632fa117e5826109e3612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a519190613dda565b610a6d5760405162461bcd60e51b81526004016108ca90613df7565b60008781526101316020908152604080832061013283528184208c855290925282209091825460ff166004811115610aa757610aa7613b5e565b14610ae95760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b89816001015414610b2c5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b602e8614610b4c5760405162461bcd60e51b81526004016108ca90613e26565b6001815460ff166001811115610b6457610b64613b5e565b03610ba55760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481d985b1a59185d1959607a1b60448201526064016108ca565b60068201546001600160a01b031660009081526101356020526040902060010154881015610c065760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b8315610c695761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015610c5057600080fd5b505afa158015610c64573d6000803e3d6000fd5b505050505b6003810188905560058101610c7f878983613ecb565b5060068101859055600781018490556040517ffbfaa6f4e508bec40137ac265a7424e16a2d209355b2f4a35de5a80ba8fec1db90610cca908b908d908b908b908e908c908c90613fb5565b60405180910390a150505050505050505050565b61012f5486906001600160a01b0316632fa117e582610cfb612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610d45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d699190613dda565b610d855760405162461bcd60e51b81526004016108ca90613df7565b60008681526101316020526040902060018101548814610dd75760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff166004811115610def57610def613b5e565b14610e345760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b602e8314610e545760405162461bcd60e51b81526004016108ca90613e26565b6001600160a01b0386166000908152610135602052604090205460ff16610eb15760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108ca565b8060070154851015610f055760405162461bcd60e51b815260206004820152601c60248201527f43616e27742072656475636520726566657272616c20616d6f756e740000000060448201526064016108ca565b60038101610f14848683613ecb565b50600781018590556006810180546001600160a01b0319166001600160a01b0388161790556040517f79dba2b7507f91f38c9a67e52f174c234541b20eccc91ad6afe9d3753f6371f590610f71908990879087908b908b90613ff4565b60405180910390a15050505050505050565b610f8b612435565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b61012f5460009089906001600160a01b0316632fa117e582611006612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611050573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110749190613dda565b6110905760405162461bcd60e51b81526004016108ca90613df7565b61109f8a8a8a8a8a8a8a6124ae565b61012e805490819060006110b283614041565b9091555050600081815261013160205260409020805460ff19168155600181018c9055600381016110e48a8c83613ecb565b50600581018b90556006810180546001600160a01b0319166001600160a01b0388161790556007810185905560008c8152610133602052604090205415801561113a575060008c81526101346020526040902054155b1561119f5761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b15801561118657600080fd5b505af115801561119a573d6000803e3d6000fd5b505050505b60008c8152610133602052604081208054916111ba83614041565b91905055507fe7f6435fc92b0ccd6f56395ae67b06f2cdb9680c0179f87f5821431304ad3f3e828d8d8d8d8b8b6040516111fa979695949392919061405a565b60405180910390a1509a9950505050505050505050565b600082815260fc602052604090206001015461122c816126b7565b61123683836126c8565b505050565b611243612426565b6001600160a01b0316816001600160a01b0316146112bb5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108ca565b6112c5828261274f565b5050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036113115760405162461bcd60e51b81526004016108ca9061409f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661135a600080516020614470833981519152546001600160a01b031690565b6001600160a01b0316146113805760405162461bcd60e51b81526004016108ca906140eb565b611389816127d4565b604080516000808252602082019092526113a5918391906127dc565b50565b6113b0612435565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee69101610fdb565b600061140c816126b7565b6101368290556040518281527f577d7afcf67637a2f602cba220bbb292c1d715380dd011bfec748c3f641b2fd29060200160405180910390a15050565b600054610100900460ff16158080156114695750600054600160ff909116105b806114835750303b158015611483575060005460ff166001145b6114e65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108ca565b6000805460ff191660011790558015611509576000805461ff0019166101001790555b611511612947565b611519612976565b611521612976565b611533600061152e612426565b61299d565b61012f80546001600160a01b038086166001600160a01b031992831617909255610130805492851692909116919091179055600161012e55611575601e611401565b8015611236576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036116085760405162461bcd60e51b81526004016108ca9061409f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611651600080516020614470833981519152546001600160a01b031690565b6001600160a01b0316146116775760405162461bcd60e51b81526004016108ca906140eb565b611680826127d4565b6112c5828260016127dc565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461172c5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108ca565b5060008051602061447083398151915290565b611747612435565b61175160006129a7565b565b61175b612435565b6001600160a01b038316158015611770575081155b156117bd5760405162461bcd60e51b815260206004820152601d60248201527f4f776e65722063616e27742072656d6f7665204f78206164647265737300000060448201526064016108ca565b6001600160a01b03831660008181526101356020908152604091829020805460ff19168615159081178255600190910185905582519384529083015281018290527f42b585a1da1cff4b571e7a78aea1b4601b1d128de41a0feebd8a77aaf48b9d88906060016115b3565b600091825260fc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61012f548a906001600160a01b0316632fa117e582611870612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156118ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118de9190613dda565b6118fa5760405162461bcd60e51b81526004016108ca90613df7565b60008a81526101316020526040902061191a8c8c8c8c8c8c8b8b8b6129f9565b60408051610100810182526000815260208082018f905260068401546001600160a01b031682840152606082018d9052608082018c90528251601f8b01829004820281018201909352898352909160a08301918b908b9081908401838280828437600081840152601f19601f8201169050808301925050505050505081526020018781526020018481525061013260008d815260200190815260200160002060008e815260200190815260200160002060008201518160000160006101000a81548160ff021916908360018111156119f4576119f4613b5e565b02179055506020820151600182015560408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a08201516005820190611a519082614137565b5060c0820151600682015560e09091015160079091015560008c81526101336020526040902054158015611a92575060008c81526101346020526040902054155b15611af75761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015611ade57600080fd5b505af1158015611af2573d6000803e3d6000fd5b505050505b60008c815261013460205260408120805491611b1283614041565b91905055507fabd26455c3256ad90125661f4c1a4c16fecf585ccade21e749c56d8fd44bb1dd8b8d8a8a60008f8f8d8b604051611b57999897969594939291906141f7565b60405180910390a1505050505050505050505050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611b97816126b7565b60008481526101316020908152604080832061013283528184208785529092529091208154600160ff1991821681178455808301546002850155600484018690558254909183911682805b0217905550505050505050565b611bf7613604565b60008381526101326020908152604080832085845290915290819020815161010081019092528054829060ff166001811115611c3557611c35613b5e565b6001811115611c4657611c46613b5e565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611c8e90613e4b565b80601f0160208091040260200160405190810160405280929190818152602001828054611cba90613e4b565b8015611d075780601f10611cdc57610100808354040283529160200191611d07565b820191906000526020600020905b815481529060010190602001808311611cea57829003601f168201915b5050505050815260200160068201548152602001600782015481525050905092915050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611d56816126b7565b6000838152610131602090815260408083206101328352818420600282015485529092528220600381015491929091611d9086606461424e565b611d9a9190614265565b9050610136548110611db657825460ff19166002178355611dc9565b8254600490849060ff1916600183611be2565b505050505050565b61013160205260009081526040902080546001820154600283015460038401805460ff909416949293919291611e0690613e4b565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3290613e4b565b8015611e7f5780601f10611e5457610100808354040283529160200191611e7f565b820191906000526020600020905b815481529060010190602001808311611e6257829003601f168201915b505050600484015460058501546006860154600790960154949591949093506001600160a01b03909116915088565b61013260209081526000928352604080842090915290825290208054600182015460028301546003840154600485015460058601805460ff9096169694956001600160a01b03909416949293919291611f0690613e4b565b80601f0160208091040260200160405190810160405280929190818152602001828054611f3290613e4b565b8015611f7f5780601f10611f5457610100808354040283529160200191611f7f565b820191906000526020600020905b815481529060010190602001808311611f6257829003601f168201915b5050505050908060060154908060070154905088565b611f9d613653565b611fa5613604565b60008481526101316020526040808220815161010081019092528054829060ff166004811115611fd757611fd7613b5e565b6004811115611fe857611fe8613b5e565b8152602001600182015481526020016002820154815260200160038201805461201090613e4b565b80601f016020809104026020016040519081016040528092919081815260200182805461203c90613e4b565b80156120895780601f1061205e57610100808354040283529160200191612089565b820191906000526020600020905b81548152906001019060200180831161206c57829003601f168201915b50505091835250506004820154602080830191909152600583015460408084019190915260068401546001600160a01b03166060840152600790930154608090920191909152600088815261013282528281208882529091528181208251610100810190935280549394509092829060ff16600181111561210c5761210c613b5e565b600181111561211d5761211d613b5e565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a09092019161216590613e4b565b80601f016020809104026020016040519081016040528092919081815260200182805461219190613e4b565b80156121de5780601f106121b3576101008083540402835291602001916121de565b820191906000526020600020905b8154815290600101906020018083116121c157829003601f168201915b505050918352505060068201546020820152600790910154604090910152919350909150505b9250929050565b600082815260fc6020526040902060010154612226816126b7565b611236838361274f565b612238613653565b61012e54821061228a5760405162461bcd60e51b815260206004820152601a60248201527f54686973207365727669636520646f65736e277420657869737400000000000060448201526064016108ca565b6000828152610131602052604090819020815161010081019092528054829060ff1660048111156122bd576122bd613b5e565b60048111156122ce576122ce613b5e565b815260200160018201548152602001600282015481526020016003820180546122f690613e4b565b80601f016020809104026020016040519081016040528092919081815260200182805461232290613e4b565b801561236f5780601f106123445761010080835404028352916020019161236f565b820191906000526020600020905b81548152906001019060200180831161235257829003601f168201915b5050509183525050600482015460208201526005820154604082015260068201546001600160a01b0316606082015260079091015460809091015292915050565b6123b8612435565b6001600160a01b03811661241d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108ca565b6113a5816129a7565b6000612430612de0565b905090565b61243d612426565b6001600160a01b03166124586033546001600160a01b031690565b6001600160a01b0316146117515760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108ca565b61013054604051638a98636360e01b8152600481018890526000916001600160a01b031690638a98636390602401602060405180830381865afa1580156124f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061251d9190614287565b90508034146125635760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b602e85146125835760405162461bcd60e51b81526004016108ca90613e26565b6001600160a01b0382166000908152610135602052604090205460ff166125e05760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108ca565b61013054604051631fff7f2760e11b8152600481018990526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa15801561262b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264f91906142a0565b90506001600160a01b038116156126ac57600089815261013360209081526040808320549051612686928d92918c918c91016142bd565b6040516020818303038152906040528051906020012090506126aa86868385612e19565b505b505050505050505050565b6113a5816126c3612426565b612f0d565b6126d28282611828565b6112c557600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561270b612426565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6127598282611828565b156112c557600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff19169055612790612426565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6113a5612435565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561280f5761123683612f66565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612869575060408051601f3d908101601f1916820190925261286691810190614287565b60015b6128cc5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108ca565b600080516020614470833981519152811461293b5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108ca565b50611236838383613002565b600054610100900460ff1661296e5760405162461bcd60e51b81526004016108ca906142fe565b61175161302d565b600054610100900460ff166117515760405162461bcd60e51b81526004016108ca906142fe565b6112c582826126c8565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61013054604051634a7ab1d560e01b8152600481018890526000916001600160a01b031690634a7ab1d590602401602060405180830381865afa158015612a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a689190614287565b9050803414612aae5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b60008981526101316020908152604080832060068101546001600160a01b03168452610135909252909120600101546007820154612aec908b614349565b1015612b2b5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b6000815460ff166004811115612b4357612b43613b5e565b14612b855760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b8060010154600003612bcd5760405162461bcd60e51b815260206004820152601160248201527014d95c9d9a58d9481b9bdd08195e1a5cdd607a1b60448201526064016108ca565b60008a8152610132602090815260408083208e84529091529020600101548b9003612c335760405162461bcd60e51b81526020600482015260166024820152751c1c9bdc1bdcd85b08185b1c9958591e48195e1a5cdd60521b60448201526064016108ca565b8a816001015403612c905760405162461bcd60e51b815260206004820152602160248201527f63616e27742063726561746520666f7220796f7572206f776e207365727669636044820152606560f81b60648201526084016108ca565b602e8614612cb05760405162461bcd60e51b81526004016108ca90613e26565b61013054604051631fff7f2760e11b8152600481018a90526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612cfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d1f91906142a0565b90506001600160a01b03811615612d6f5760008c8c8a8a604051602001612d49949392919061435c565b604051602081830303815290604052805190602001209050612d6d87878385612e19565b505b8315612dd25761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015612db957600080fd5b505afa158015612dcd573d6000803e3d6000fd5b505050505b505050505050505050505050565b600060143610801590612e0257503360009081526065602052604090205460ff165b15612e14575060131936013560601c90565b503390565b6000612e72836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000612eb68287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061306492505050565b9050806001600160a01b0316836001600160a01b031614611dc95760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064016108ca565b612f178282611828565b6112c557612f2481613088565b612f2f83602061309a565b604051602001612f4092919061439e565b60408051601f198184030181529082905262461bcd60e51b82526108ca91600401614413565b6001600160a01b0381163b612fd35760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108ca565b60008051602061447083398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61300b8361323d565b6000825111806130185750805b1561123657613027838361327d565b50505050565b600054610100900460ff166130545760405162461bcd60e51b81526004016108ca906142fe565b61175161305f612426565b6129a7565b60008060006130738585613371565b91509150613080816133b3565b509392505050565b606061081d6001600160a01b03831660145b606060006130a983600261424e565b6130b4906002614349565b67ffffffffffffffff8111156130cc576130cc61395c565b6040519080825280601f01601f1916602001820160405280156130f6576020820181803683370190505b509050600360fc1b8160008151811061311157613111614426565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061314057613140614426565b60200101906001600160f81b031916908160001a905350600061316484600261424e565b61316f906001614349565b90505b60018111156131e7576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106131a3576131a3614426565b1a60f81b8282815181106131b9576131b9614426565b60200101906001600160f81b031916908160001a90535060049490941c936131e08161443c565b9050613172565b5083156132365760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108ca565b9392505050565b61324681612f66565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6132e55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108ca565b600080846001600160a01b0316846040516133009190614453565b600060405180830381855af49150503d806000811461333b576040519150601f19603f3d011682016040523d82523d6000602084013e613340565b606091505b50915091506133688282604051806060016040528060278152602001614490602791396134fd565b95945050505050565b60008082516041036133a75760208301516040840151606085015160001a61339b87828585613516565b94509450505050612204565b50600090506002612204565b60008160048111156133c7576133c7613b5e565b036133cf5750565b60018160048111156133e3576133e3613b5e565b036134305760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108ca565b600281600481111561344457613444613b5e565b036134915760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108ca565b60038160048111156134a5576134a5613b5e565b036113a55760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108ca565b6060831561350c575081613236565b61323683836135da565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561354d57506000905060036135d1565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156135a1573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166135ca576000600192509250506135d1565b9150600090505b94509492505050565b8151156135ea5781518083602001fd5b8060405162461bcd60e51b81526004016108ca9190614413565b60408051610100810190915280600081526020016000815260200160006001600160a01b0316815260200160008152602001600081526020016060815260200160008152602001600081525090565b6040805161010081019091528060008152602001600081526020016000815260200160608152602001600081526020016000815260200160006001600160a01b03168152602001600081525090565b6000602082840312156136b457600080fd5b81356001600160e01b03198116811461323657600080fd5b600080604083850312156136df57600080fd5b50508035926020909101359150565b60008083601f84011261370057600080fd5b50813567ffffffffffffffff81111561371857600080fd5b60208301915083602082850101111561220457600080fd5b600080600080600080600060c0888a03121561374b57600080fd5b873596506020880135955060408801359450606088013567ffffffffffffffff81111561377757600080fd5b6137838a828b016136ee565b989b979a50959895979660808701359660a0013595509350505050565b6001600160a01b03811681146113a557600080fd5b60008060008060008060a087890312156137ce57600080fd5b863595506020870135945060408701356137e7816137a0565b935060608701359250608087013567ffffffffffffffff81111561380a57600080fd5b61381689828a016136ee565b979a9699509497509295939492505050565b60006020828403121561383a57600080fd5b5035919050565b60006020828403121561385357600080fd5b8135613236816137a0565b60008060008060008060008060c0898b03121561387a57600080fd5b8835975060208901359650604089013567ffffffffffffffff808211156138a057600080fd5b6138ac8c838d016136ee565b909850965060608b01359150808211156138c557600080fd5b506138d28b828c016136ee565b90955093505060808901356138e6816137a0565b8092505060a089013590509295985092959890939650565b6000806040838503121561391157600080fd5b823591506020830135613923816137a0565b809150509250929050565b6000806040838503121561394157600080fd5b823561394c816137a0565b91506020830135613923816137a0565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561398557600080fd5b8235613990816137a0565b9150602083013567ffffffffffffffff808211156139ad57600080fd5b818501915085601f8301126139c157600080fd5b8135818111156139d3576139d361395c565b604051601f8201601f19908116603f011681019083821181831017156139fb576139fb61395c565b81604052828152886020848701011115613a1457600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b80151581146113a557600080fd5b600080600060608486031215613a5957600080fd5b8335613a64816137a0565b92506020840135613a7481613a36565b929592945050506040919091013590565b6000806000806000806000806000806101008b8d031215613aa557600080fd5b8a35995060208b0135985060408b0135975060608b0135965060808b013567ffffffffffffffff80821115613ad957600080fd5b613ae58e838f016136ee565b909850965060a08d0135955060c08d0135915080821115613b0557600080fd5b50613b128d828e016136ee565b9150809450508092505060e08b013590509295989b9194979a5092959850565b600080600060608486031215613b4757600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052602160045260246000fd5b60028110613b8457613b84613b5e565b9052565b60005b83811015613ba3578181015183820152602001613b8b565b50506000910152565b60008151808452613bc4816020860160208601613b88565b601f01601f19169290920160200192915050565b6000610100613be8848451613b74565b6020830151602085015260018060a01b036040840151166040850152606083015160608501526080830151608085015260a08301518160a0860152613c2f82860182613bac565b91505060c083015160c085015260e083015160e08501528091505092915050565b6020815260006132366020830184613bd8565b60058110613b8457613b84613b5e565b6000610100613c82838c613c63565b896020840152886040840152806060840152613ca081840189613bac565b6080840197909752505060a08101939093526001600160a01b039190911660c083015260e090910152949350505050565b6000610100613ce0838c613b74565b89602084015260018060a01b03891660408401528760608401528660808401528060a0840152613d1281840187613bac565b60c0840195909552505060e001529695505050505050565b6000610100613d3a848451613c63565b60208301516020850152604083015160408501526060830151816060860152613d6582860182613bac565b6080858101519087015260a0808601519087015260c0808601516001600160a01b03169087015260e0948501519490950193909352509192915050565b604081526000613db56040830185613d2a565b82810360208401526133688185613bd8565b6020815260006132366020830184613d2a565b600060208284031215613dec57600080fd5b815161323681613a36565b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b6020808252600b908201526a125b9d985b1a590818da5960aa1b604082015260600190565b600181811c90821680613e5f57607f821691505b602082108103613e7f57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561123657600081815260208120601f850160051c81016020861015613eac5750805b601f850160051c820191505b81811015611dc957828155600101613eb8565b67ffffffffffffffff831115613ee357613ee361395c565b613ef783613ef18354613e4b565b83613e85565b6000601f841160018114613f2b5760008515613f135750838201355b600019600387901b1c1916600186901b178355613f85565b600083815260209020601f19861690835b82811015613f5c5786850135825560209485019460019092019101613f3c565b5086821015613f795760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b87815286602082015260c060408201526000613fd560c083018789613f8c565b606083019590955250608081019290925260a090910152949350505050565b85815260806020820152600061400e608083018688613f8c565b6001600160a01b0394909416604083015250606001529392505050565b634e487b7160e01b600052601160045260246000fd5b6000600182016140535761405361402b565b5060010190565b87815286602082015285604082015260c06060820152600061408060c083018688613f8c565b6001600160a01b039490941660808301525060a0015295945050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b815167ffffffffffffffff8111156141515761415161395c565b6141658161415f8454613e4b565b84613e85565b602080601f83116001811461419a57600084156141825750858301515b600019600386901b1c1916600185901b178555611dc9565b600085815260208120601f198616915b828110156141c9578886015182559484019460019091019084016141aa565b50858210156141e75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006101008b83528a60208401528060408401526142188184018a8c613f8c565b9150506142286060830188613b74565b8560808301528460a08301528360c08301528260e08301529a9950505050505050505050565b808202811582820484141761081d5761081d61402b565b60008261428257634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561429957600080fd5b5051919050565b6000602082840312156142b257600080fd5b8151613236816137a0565b6c6372656174655365727669636560981b815284600d820152603b60f81b602d82015283602e8201528183604e83013760009101604e019081529392505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8082018082111561081d5761081d61402b565b6d18dc99585d19541c9bdc1bdcd85b60921b815284600e820152603b60f81b602e82015283602f8201528183604f83013760009101604f019081529392505050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516143d6816017850160208801613b88565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351614407816028840160208801613b88565b01602801949350505050565b6020815260006132366020830184613bac565b634e487b7160e01b600052603260045260246000fd5b60008161444b5761444b61402b565b506000190190565b60008251614465818460208701613b88565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a1ba7d9ed8bda0e85592c39f8b8a90f379bcd674d0b9fd980896e2501b6dde2264736f6c63430008110033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/packages/client/src/services/index.ts b/packages/client/src/services/index.ts index 4d152e9..963e0f1 100644 --- a/packages/client/src/services/index.ts +++ b/packages/client/src/services/index.ts @@ -105,6 +105,7 @@ export class Service implements IService { serviceDetails: ServiceDetails, userId: string, serviceId: number, + rateToken: string, referralAmount: string = '0', ): Promise { const cid = await this.updloadServiceDataToIpfs(serviceDetails); @@ -112,7 +113,7 @@ export class Service implements IService { const tx = await this.viemClient.writeContract( 'talentLayerService', 'updateService', - [userId, serviceId, referralAmount, cid] + [userId, serviceId, rateToken, referralAmount, cid] ); if (cid && tx) { diff --git a/packages/client/src/services/types/index.ts b/packages/client/src/services/types/index.ts index ce294cf..4adb55f 100644 --- a/packages/client/src/services/types/index.ts +++ b/packages/client/src/services/types/index.ts @@ -14,6 +14,7 @@ export interface IService { serviceDetails: ServiceDetails, userId: string, serviceId: number, + rateToken: string, referralAmount?: string, ): Promise; updloadServiceDataToIpfs(serviceData: ServiceDetails): Promise; From 2a82d2d3f243e619bc75e52304fc62c130947a3b Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Fri, 1 Dec 2023 17:51:49 +0000 Subject: [PATCH 28/40] Reverted updateService function --- packages/client/src/contracts/ABI/TalentLayerService.json | 6 ------ packages/client/src/services/index.ts | 3 +-- packages/client/src/services/types/index.ts | 1 - 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/packages/client/src/contracts/ABI/TalentLayerService.json b/packages/client/src/contracts/ABI/TalentLayerService.json index 66f6380..3153a47 100644 --- a/packages/client/src/contracts/ABI/TalentLayerService.json +++ b/packages/client/src/contracts/ABI/TalentLayerService.json @@ -354,12 +354,6 @@ "name": "dataUri", "type": "string" }, - { - "indexed": false, - "internalType": "address", - "name": "rateToken", - "type": "address" - }, { "indexed": false, "internalType": "uint256", diff --git a/packages/client/src/services/index.ts b/packages/client/src/services/index.ts index 963e0f1..4d152e9 100644 --- a/packages/client/src/services/index.ts +++ b/packages/client/src/services/index.ts @@ -105,7 +105,6 @@ export class Service implements IService { serviceDetails: ServiceDetails, userId: string, serviceId: number, - rateToken: string, referralAmount: string = '0', ): Promise { const cid = await this.updloadServiceDataToIpfs(serviceDetails); @@ -113,7 +112,7 @@ export class Service implements IService { const tx = await this.viemClient.writeContract( 'talentLayerService', 'updateService', - [userId, serviceId, rateToken, referralAmount, cid] + [userId, serviceId, referralAmount, cid] ); if (cid && tx) { diff --git a/packages/client/src/services/types/index.ts b/packages/client/src/services/types/index.ts index 4adb55f..ce294cf 100644 --- a/packages/client/src/services/types/index.ts +++ b/packages/client/src/services/types/index.ts @@ -14,7 +14,6 @@ export interface IService { serviceDetails: ServiceDetails, userId: string, serviceId: number, - rateToken: string, referralAmount?: string, ): Promise; updloadServiceDataToIpfs(serviceData: ServiceDetails): Promise; From b222116fd5128278db43d9f84b1d4aec1f45ab9e Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Sat, 2 Dec 2023 00:19:09 +0530 Subject: [PATCH 29/40] added support for custom chain config --- packages/client/src/__mocks__/clientMocks.ts | 3 +- .../client/src/blockchain-bindings/erc20.ts | 13 +++---- .../src/disputes/__tests__/disputes.spec.ts | 11 ++++-- packages/client/src/disputes/index.ts | 17 ++++++--- .../src/escrow/__tests__/escrow.spec.ts | 6 ++- packages/client/src/escrow/index.ts | 11 ++++-- packages/client/src/index.ts | 26 +++++++++++-- packages/client/src/platform/index.ts | 4 +- packages/client/src/types/index.ts | 25 ++++++++++-- packages/client/src/utils/typeguard.ts | 9 +++++ packages/client/src/viem/index.ts | 38 ++++++++++++------- 11 files changed, 119 insertions(+), 44 deletions(-) create mode 100644 packages/client/src/utils/typeguard.ts diff --git a/packages/client/src/__mocks__/clientMocks.ts b/packages/client/src/__mocks__/clientMocks.ts index 7c46e7b..56d977c 100644 --- a/packages/client/src/__mocks__/clientMocks.ts +++ b/packages/client/src/__mocks__/clientMocks.ts @@ -1,3 +1,4 @@ +import { polygon } from "viem/chains"; import { getPaymentsByService, getProtocolAndPlatformsFees } from "../escrow/graphql/queries"; import { getPlatformById, getPlatformsByOwner, getProtocolById } from "../platform/graphql/queries"; import { getMintFees, getPaymentsForUser, getProfileByAddress, getProfileById, getProfiles, getUserTotalGains } from "../profile/graphql"; @@ -91,7 +92,7 @@ export class MockGraphQLClient { export class MockViemClient { writeContract = jest.fn(async () => testAddress) - chainId = 137; + chain = polygon; readContract = jest.fn(async () => "randomData") publicClient = { readContract: jest.fn(async () => "randomData"), diff --git a/packages/client/src/blockchain-bindings/erc20.ts b/packages/client/src/blockchain-bindings/erc20.ts index d98b9da..592f50f 100644 --- a/packages/client/src/blockchain-bindings/erc20.ts +++ b/packages/client/src/blockchain-bindings/erc20.ts @@ -2,8 +2,7 @@ import IPFSClient from '../ipfs'; import ERC20Contract from '../contracts/ABI/ERC20.json'; import { ViemClient } from '../viem'; -import { getChainConfig } from '../config'; -import { NetworkEnum } from '../types'; +import { ChainConfig } from '../types'; export interface IERC20 { balanceOf(tokenAddress: `0x${string}`): Promise; @@ -15,20 +14,20 @@ export class ERC20 { ipfsClient: IPFSClient; viemClient: ViemClient; platformID: number; - chainId: NetworkEnum; + chainConfig: ChainConfig; constructor( ipfsClient: IPFSClient, viemClient: ViemClient, platformId: number, - chainId: NetworkEnum, + chainConfig: ChainConfig ) { console.log('SDK: erc20 initialising: '); this.platformID = platformId; this.ipfsClient = ipfsClient; this.viemClient = viemClient; - this.chainId = chainId; + this.chainConfig = chainConfig; } public async balanceOf(tokenAddress: `0x${string}`): Promise { @@ -50,7 +49,7 @@ export class ERC20 { // @ts-ignore const [address] = await this.viemClient.client.getAddresses(); - const chainConfig = getChainConfig(this.chainId); + const chainConfig = this.chainConfig; const contract = chainConfig.contracts['talentLayerEscrow']; // @ts-ignore @@ -68,7 +67,7 @@ export class ERC20 { // @ts-ignore const [address] = await this.viemClient.client.getAddresses(); - const chainConfig = getChainConfig(this.chainId); + const chainConfig = this.chainConfig; const contract = chainConfig.contracts['talentLayerEscrow']; // @ts-ignore diff --git a/packages/client/src/disputes/__tests__/disputes.spec.ts b/packages/client/src/disputes/__tests__/disputes.spec.ts index c1dc293..bebe17d 100644 --- a/packages/client/src/disputes/__tests__/disputes.spec.ts +++ b/packages/client/src/disputes/__tests__/disputes.spec.ts @@ -1,8 +1,8 @@ import { parseEther, toHex } from "viem"; import { Disputes } from ".."; import { getChainConfig, getGraphQLConfig } from "../../config"; -import GraphQLClient from "../../graphql"; import { getPlatformById } from "../../platform/graphql/queries"; +import { ChainConfig } from "../../types"; import { MockGraphQLClient, MockViemClient } from "../../__mocks__/clientMocks"; import { testPlatformId, testChainId, testPlatformResponseWithArbitrator, testAddress } from "../../__mocks__/fixtures"; @@ -11,13 +11,15 @@ describe('Disputes', () => { let mockGraphQLClient: any; let mockViemClient: any; let disputes: Disputes; + let mockChainConfig: ChainConfig; beforeEach(() => { mockGraphQLClient = new MockGraphQLClient(); // DO NOT remove this comments - they are needed for local testing // mockGraphQLClient = new GraphQLClient(getGraphQLConfig(137)) mockViemClient = new MockViemClient(); - disputes = new Disputes(mockViemClient, testPlatformId, mockGraphQLClient, testChainId); + mockChainConfig = getChainConfig(testChainId); + disputes = new Disputes(mockViemClient, testPlatformId, mockGraphQLClient, mockChainConfig); }); it('constructor initializes correctly', () => { @@ -41,8 +43,9 @@ describe('Disputes', () => { it('should read arbitration contract and return value if arbitrator address is not zero', async () => { // Arrange // set a new disputes instance with a different platform id - disputes = new Disputes(mockViemClient, 2, mockGraphQLClient, testChainId); - const chainConfig = getChainConfig(disputes.chainId); + mockChainConfig = getChainConfig(testChainId); + disputes = new Disputes(mockViemClient, 2, mockGraphQLClient, mockChainConfig); + const chainConfig = mockChainConfig const contract = chainConfig.contracts['talentLayerArbitrator']; //Act diff --git a/packages/client/src/disputes/index.ts b/packages/client/src/disputes/index.ts index 6323c33..aab0e72 100644 --- a/packages/client/src/disputes/index.ts +++ b/packages/client/src/disputes/index.ts @@ -1,8 +1,7 @@ import { Hash, parseEther, toHex, zeroAddress } from 'viem'; -import { getChainConfig } from '../config'; import GraphQLClient from '../graphql'; import { getPlatformById } from '../platform/graphql/queries'; -import { NetworkEnum } from '../types'; +import { ChainConfig, NetworkEnum } from '../types'; import { ViemClient } from '../viem'; /** @@ -11,20 +10,26 @@ import { ViemClient } from '../viem'; * @group TalentLayerClient Modules */ export class Disputes { + /** @hidden */ wallet: ViemClient; + /** @hidden */ platformID: number; + /** @hidden */ subgraph: GraphQLClient; - chainId: NetworkEnum; + /** @hidden */ + chainConfig: ChainConfig; + + /** @hidden */ constructor( walletClient: ViemClient, platformId: number, graphQlClient: GraphQLClient, - chainId: number, + chainConfig: ChainConfig ) { this.wallet = walletClient; this.platformID = platformId; this.subgraph = graphQlClient; - this.chainId = chainId; + this.chainConfig = chainConfig; } /** @@ -45,7 +50,7 @@ export class Disputes { return 0; } - const chainConfig = getChainConfig(this.chainId); + const chainConfig = this.chainConfig; const contract = chainConfig.contracts['talentLayerArbitrator']; console.log('SDK: reading contract'); diff --git a/packages/client/src/escrow/__tests__/escrow.spec.ts b/packages/client/src/escrow/__tests__/escrow.spec.ts index aa76a2c..8e5fde0 100644 --- a/packages/client/src/escrow/__tests__/escrow.spec.ts +++ b/packages/client/src/escrow/__tests__/escrow.spec.ts @@ -1,5 +1,7 @@ import { Escrow } from '..'; +import { getChainConfig } from '../../config'; +import { ChainConfig } from '../../types'; import { MockGraphQLClient, MockIPFSClient, MockViemClient } from '../../__mocks__/clientMocks'; import { testAddress, testAmount, testChainId, testCid, testIpfsHash, testMetaEvidenceCid, testPlatformId, testProposalId, testProposalIdWithDifferentRateToken, testProposalResponse, testProtocolAndPlatformResponse, testServiceId, testServiceResponse, testUserId } from '../../__mocks__/fixtures'; // DO NOT remove this comments - they are needed for local testing @@ -12,6 +14,7 @@ describe('Escrow', () => { let mockGraphQLClient: any; let mockIPFSClient: any; let mockViemClient: any; + let mockChainConfig: ChainConfig; beforeEach(() => { mockGraphQLClient = new MockGraphQLClient(); @@ -19,7 +22,8 @@ describe('Escrow', () => { // mockGraphQLClient = new GraphQLClient(getGraphQLConfig(137)) mockIPFSClient = new MockIPFSClient(); mockViemClient = new MockViemClient(); - escrow = new Escrow(mockGraphQLClient, mockIPFSClient, mockViemClient, testPlatformId, testChainId); + mockChainConfig = getChainConfig(testChainId); + escrow = new Escrow(mockGraphQLClient, mockIPFSClient, mockViemClient, testPlatformId, testChainId, mockChainConfig); }); describe('approve', () => { diff --git a/packages/client/src/escrow/index.ts b/packages/client/src/escrow/index.ts index 1fcad81..ed0e1df 100644 --- a/packages/client/src/escrow/index.ts +++ b/packages/client/src/escrow/index.ts @@ -3,7 +3,7 @@ import GraphQLClient from '../graphql'; import IPFSClient from '../ipfs'; import { Proposal } from '../proposals'; import { Service } from '../services'; -import { ClientTransactionResponse, NetworkEnum, RateToken } from '../types'; +import { ChainConfig, ClientTransactionResponse, NetworkEnum, RateToken } from '../types'; import { calculateApprovalAmount } from '../utils/fees'; import { ViemClient } from '../viem'; import { getPaymentsByService, getProtocolAndPlatformsFees } from './graphql/queries'; @@ -29,6 +29,8 @@ export class Escrow { chainId: NetworkEnum; /** @hidden */ erc20: IERC20; + /** @hidden */ + chainConfig: ChainConfig; /** @hidden */ constructor( @@ -37,14 +39,17 @@ export class Escrow { viemClient: ViemClient, platformId: number, chainId: NetworkEnum, + chainConfig: ChainConfig + ) { - console.log('SDK: escrow initialising: '); + console.log('SDK: escrow initialising'); this.graphQlClient = graphQlClient; this.platformID = platformId; this.ipfsClient = ipfsClient; this.viemClient = viemClient; this.chainId = chainId; - this.erc20 = new ERC20(this.ipfsClient, this.viemClient, this.platformID, this.chainId); + this.chainConfig = chainConfig; + this.erc20 = new ERC20(this.ipfsClient, this.viemClient, this.platformID, this.chainConfig); } public async approve( diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index 9918b75..76e3c5f 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -1,6 +1,6 @@ import { getChainConfig, getGraphQLConfig } from './config'; import GraphQLClient from './graphql'; -import { Config, NetworkEnum, TalentLayerClientConfig } from './types'; +import { Config, CustomChainConfig, NetworkEnum, TalentLayerClientConfig } from './types'; import IPFSClient from './ipfs'; import { ViemClient } from './viem'; import { IERC20, ERC20 } from './blockchain-bindings/erc20'; @@ -34,6 +34,8 @@ export class TalentLayerClient { chainId: NetworkEnum; /** @hidden */ signatureApiUrl?: string; + /** @hidden */ + chainConfig: Config | CustomChainConfig; /** @hidden */ constructor(config: TalentLayerClientConfig) { @@ -45,9 +47,16 @@ export class TalentLayerClient { clientId: config.ipfsConfig.clientId, clientSecret: config.ipfsConfig.clientSecret, }); - this.viemClient = new ViemClient(config.chainId, config.walletConfig || {}); + this.chainId = config.chainId; this.signatureApiUrl = config?.signatureApiUrl; + this.chainConfig = getChainConfig(config.chainId); + + if (config.customChainConfig) { + this.chainConfig = config.customChainConfig + } + + this.viemClient = new ViemClient({ ...config.walletConfig, chainConfig: this.chainConfig }); } /** @@ -57,13 +66,21 @@ export class TalentLayerClient { return getChainConfig(networkId); } + + /** + * Returns chain config for current isntance of SDK + */ + public getCurrentChainConfig(): Config { + return this.chainConfig + } + /** * Provides access to ERC20 token functionalities. * @type {IERC20} */ // @ts-ignore get erc20(): IERC20 { - return new ERC20(this.ipfsClient, this.viemClient, this.platformID, this.chainId); + return new ERC20(this.ipfsClient, this.viemClient, this.platformID, this.chainConfig); } /** @@ -97,7 +114,7 @@ export class TalentLayerClient { */ // @ts-ignore get disputes(): IDispute { - return new Disputes(this.viemClient, this.platformID, this.graphQlClient, this.chainId); + return new Disputes(this.viemClient, this.platformID, this.graphQlClient, this.chainConfig); } /** @@ -146,6 +163,7 @@ export class TalentLayerClient { this.viemClient, this.platformID, this.chainId, + this.chainConfig ); } } diff --git a/packages/client/src/platform/index.ts b/packages/client/src/platform/index.ts index 8cbf6d3..cfb7357 100644 --- a/packages/client/src/platform/index.ts +++ b/packages/client/src/platform/index.ts @@ -140,14 +140,14 @@ export class Platform { * @returns {Promise} A promise that resolves to the transaction hash of the update operation. */ public async updateArbitrator(address: Hash): Promise { - const allowedArbitrators: Arbitrator[] = this.getArbitrators(this.wallet.chainId); + const allowedArbitrators: Arbitrator[] = this.getArbitrators(this.wallet.chain.id); const allowedArbitratorAddresses = allowedArbitrators.map((_arbitrator: Arbitrator) => _arbitrator.address.toLowerCase(), ); if (!allowedArbitratorAddresses.includes(address.toLowerCase())) { - throw new Error(`Invalid Arbitrator: ${address}`); + throw new Error(`Invalid Arbitrator: ${address} allowed arbitrators: ${JSON.stringify(allowedArbitratorAddresses)}`); } const tx = await this.wallet.writeContract('talentLayerPlatformId', 'updateArbitrator', [ diff --git a/packages/client/src/types/index.ts b/packages/client/src/types/index.ts index c61ea71..ee0f3c3 100644 --- a/packages/client/src/types/index.ts +++ b/packages/client/src/types/index.ts @@ -1,4 +1,4 @@ -import { Hash } from 'viem'; +import { Chain, Hash } from 'viem'; export type IToken = { name: string; @@ -18,6 +18,9 @@ export enum RateToken { NATIVE = '0x0000000000000000000000000000000000000000', } +/** + * Defines the Config type for predefined chains supported by TalentLayer +*/ export type Config = { networkId: NetworkEnum; subgraphUrl: string; @@ -26,6 +29,17 @@ export type Config = { tokens: { [key: string]: IToken }; }; +export type CustomChainConfig = { + networkId: number; + chainDefinition: Chain; + subgraphUrl: string; + escrowConfig: { [key: string]: any }; + contracts: { [key: string]: { address: `0x${string}`; abi: any } }; + tokens: { [key: string]: IToken }; +} + +export type ChainConfig = Config | CustomChainConfig; + export type GraphQLConfig = { chainId: NetworkEnum; subgraphUrl: string; @@ -43,15 +57,20 @@ export type ViemClientConfig = { rpcUrl?: string; privateKey?: `0x${string}`; mnemonic?: string; - chainId?: NetworkEnum; + chainConfig: ChainConfig; }; export type TalentLayerClientConfig = { chainId: NetworkEnum; ipfsConfig: IPFSClientConfig; - walletConfig?: ViemClientConfig; + walletConfig?: { + rpcUrl?: string; + privateKey?: `0x${string}`; + mnemonic?: string; + }; platformId: number; signatureApiUrl?: string; + customChainConfig?: ChainConfig; }; /** diff --git a/packages/client/src/utils/typeguard.ts b/packages/client/src/utils/typeguard.ts new file mode 100644 index 0000000..591cff9 --- /dev/null +++ b/packages/client/src/utils/typeguard.ts @@ -0,0 +1,9 @@ +import { ChainConfig, CustomChainConfig } from "../types" + +// const isNecklace = (b: Accessory): b is Necklace => { +// return (b as Necklace).kind !== undefined +// } + +export const isCustomChainConfig = (config: ChainConfig): config is CustomChainConfig => { + return (config as CustomChainConfig).chainDefinition !== undefined; +} \ No newline at end of file diff --git a/packages/client/src/viem/index.ts b/packages/client/src/viem/index.ts index efa2769..6647643 100644 --- a/packages/client/src/viem/index.ts +++ b/packages/client/src/viem/index.ts @@ -6,29 +6,41 @@ import { WalletClient, PublicClient, Hash, + defineChain, + Chain, } from 'viem'; import { mnemonicToAccount, privateKeyToAccount } from 'viem/accounts'; -import { getChainConfig } from '../config'; -import { NetworkEnum, ViemClientConfig } from '../types'; +import { ChainConfig, CustomChainConfig, NetworkEnum, ViemClientConfig } from '../types'; import TalentLayerID from '../contracts/ABI/TalentLayerID.json'; import { chains } from '../blockchain-bindings/chains'; +import { isCustomChainConfig } from '../utils/typeguard'; export class ViemClient { client: WalletClient; publicClient: PublicClient; - chainId: NetworkEnum; + chainConfig: ChainConfig; + chain: Chain; - constructor(chainId: NetworkEnum, config: ViemClientConfig) { + constructor(config: ViemClientConfig) { // if chainId is not provided, set it to mumbai - this.chainId = chainId || config.chainId || NetworkEnum.MUMBAI; + this.chainConfig = config.chainConfig; + let chain; + if (isCustomChainConfig(config.chainConfig)) { + chain = defineChain((config.chainConfig as CustomChainConfig).chainDefinition) + } else { + chain = chains[config.chainConfig.networkId as NetworkEnum] + } + console.log('viem client initialising: ', chain.id) + + this.chain = chain; // initialise a default public wallet client; this.client = createWalletClient({ - chain: chains[this.chainId], + chain, transport: http(), }); this.publicClient = createPublicClient({ - chain: chains[this.chainId], + chain, transport: http(), }); @@ -45,7 +57,7 @@ export class ViemClient { const account = privateKeyToAccount(config.privateKey); this.client = createWalletClient({ account, - chain: chains[this.chainId], + chain: this.chain, transport: transportProtocol, }); @@ -56,7 +68,7 @@ export class ViemClient { const account = mnemonicToAccount(config.mnemonic); this.client = createWalletClient({ account, - chain: chains[this.chainId], + chain: this.chain, transport: transportProtocol, }); @@ -67,7 +79,7 @@ export class ViemClient { let browserProvider = globalThis?.ethereum || window?.ethereum; if (browserProvider) { this.client = createWalletClient({ - chain: chains[this.chainId], + chain: this.chain, transport: custom(browserProvider), }); return true; @@ -89,7 +101,7 @@ export class ViemClient { throw Error('Wallet Client not initialised properly'); } - const chainConfig = getChainConfig(this.chainId); + const chainConfig = this.chainConfig; const contract = chainConfig.contracts[contractName]; if (!contract) { @@ -113,7 +125,7 @@ export class ViemClient { } public async readContract(contractName: string, functionName: string, args: Array) { - const chainConfig = getChainConfig(this.chainId); + const chainConfig = this.chainConfig; const contract = chainConfig.contracts[contractName]; console.log('SDK: reading contract', contract); @@ -138,7 +150,7 @@ export class ViemClient { throw Error('Wallet Client not initialised properly'); } - const chainConfig = getChainConfig(this.chainId); + const chainConfig = this.chainConfig; // @ts-ignore return this.client.writeContract({ From 799e2c0345fb7c3514409185e7c86f67e3e0a7a6 Mon Sep 17 00:00:00 2001 From: pranavsinghal Date: Sat, 2 Dec 2023 00:45:40 +0530 Subject: [PATCH 30/40] added test case for sdk intialised with customChainConfig --- .../src/__tests__/talentLayerClient.spec.ts | 122 +++++++++++++++++- .../src/escrow/__tests__/escrow.spec.ts | 2 +- packages/client/src/escrow/index.ts | 4 - packages/client/src/index.ts | 21 ++- packages/client/src/types/index.ts | 2 +- packages/client/src/utils/typeguard.ts | 6 +- 6 files changed, 139 insertions(+), 18 deletions(-) diff --git a/packages/client/src/__tests__/talentLayerClient.spec.ts b/packages/client/src/__tests__/talentLayerClient.spec.ts index 71bd22e..3f09cff 100644 --- a/packages/client/src/__tests__/talentLayerClient.spec.ts +++ b/packages/client/src/__tests__/talentLayerClient.spec.ts @@ -8,7 +8,8 @@ import { Profile } from '../profile'; import { Proposal } from '../proposals'; import { Review } from '../reviews'; import { Service } from '../services'; -import { testPlatformId } from '../__mocks__/fixtures'; +import { CustomChainConfig } from '../types'; +import { testAddress, testPlatformId } from '../__mocks__/fixtures'; jest.mock('axios') @@ -30,8 +31,7 @@ describe('TalentLayerClient', () => { clientSecret: 'abcde', baseUrl: 'www.example.com' } - const viemConfig = {}; - const platformID = testPlatformId; + const signatureApiUrl = 'www.example.com'; client = new TalentLayerClient({ chainId: chainId, @@ -62,4 +62,118 @@ describe('TalentLayerClient', () => { expect(client.review).toBeInstanceOf(Review) }) }) -}); \ No newline at end of file +}); + +describe('TalentLayerClient:customchainConfig', () => { + let client: any; + + beforeEach(() => { + Object.defineProperty(globalThis, 'window', { + }); + const chainDefintion = { + id: 134, + name: 'iExec Sidechain', + network: 'iexec', + nativeCurrency: { + decimals: 18, + name: 'xRLC', + symbol: 'xRLC', + }, + rpcUrls: { + default: { + http: ['https://bellecour.iex.ec'], + }, + public: { + http: ['https://bellecour.iex.ec'], + }, + }, + blockExplorers: { + default: { + name: 'BlockScout', + url: 'https://blockscout-bellecour.iex.ec/', + }, + }, + testnet: false, + }; + + const customChainConfig: CustomChainConfig = { + networkId: 135, + chainDefinition: chainDefintion, + subgraphUrl: 'www.example.com', + contracts: { + talentLayerId: { + address: testAddress, + abi: {} + } + }, + escrowConfig: { + adminFee: '0', + adminWallet: testAddress, + timeoutPayment: 100, + }, + tokens: { + [testAddress]: { + address: testAddress, + symbol: 'RAC', + name: 'RACOON', + decimals: 18, + } + } + } + const ipfsConfig = { + clientId: 'abcd', + clientSecret: 'abcde', + baseUrl: 'www.example.com' + } + + const signatureApiUrl = 'www.example.com'; + client = new TalentLayerClient({ + ipfsConfig: ipfsConfig, + platformId: testPlatformId, + signatureApiUrl: signatureApiUrl, + customChainConfig + }) + + + }) + + + describe('constructor', () => { + it('should be initialised successfully when chain config is passed', () => { + expect(client).toBeDefined() + + }) + + it('should throw error if the sdk is intialised without networkId and customChainConfig', () => { + const ipfsConfig = { + clientId: 'abcd', + clientSecret: 'abcde', + baseUrl: 'www.example.com' + } + + const signatureApiUrl = 'www.example.com'; + expect(() => { + new TalentLayerClient({ + ipfsConfig: ipfsConfig, + platformId: testPlatformId, + signatureApiUrl: signatureApiUrl + }) + }).toThrow('Atleast one of chainId or customChainConfig need to be provided') + + + }) + }) + + describe('getters', () => { + it('should return all domain specific getters', async () => { + expect(client.platform).toBeInstanceOf(Platform) + expect(client.erc20).toBeInstanceOf(ERC20) + expect(client.proposal).toBeInstanceOf(Proposal) + expect(client.disputes).toBeInstanceOf(Disputes) + expect(client.service).toBeInstanceOf(Service) + expect(client.profile).toBeInstanceOf(Profile) + expect(client.escrow).toBeInstanceOf(Escrow) + expect(client.review).toBeInstanceOf(Review) + }) + }) +}) \ No newline at end of file diff --git a/packages/client/src/escrow/__tests__/escrow.spec.ts b/packages/client/src/escrow/__tests__/escrow.spec.ts index 8e5fde0..38125be 100644 --- a/packages/client/src/escrow/__tests__/escrow.spec.ts +++ b/packages/client/src/escrow/__tests__/escrow.spec.ts @@ -23,7 +23,7 @@ describe('Escrow', () => { mockIPFSClient = new MockIPFSClient(); mockViemClient = new MockViemClient(); mockChainConfig = getChainConfig(testChainId); - escrow = new Escrow(mockGraphQLClient, mockIPFSClient, mockViemClient, testPlatformId, testChainId, mockChainConfig); + escrow = new Escrow(mockGraphQLClient, mockIPFSClient, mockViemClient, testPlatformId, mockChainConfig); }); describe('approve', () => { diff --git a/packages/client/src/escrow/index.ts b/packages/client/src/escrow/index.ts index ed0e1df..af316af 100644 --- a/packages/client/src/escrow/index.ts +++ b/packages/client/src/escrow/index.ts @@ -26,8 +26,6 @@ export class Escrow { /** @hidden */ platformID: number; /** @hidden */ - chainId: NetworkEnum; - /** @hidden */ erc20: IERC20; /** @hidden */ chainConfig: ChainConfig; @@ -38,7 +36,6 @@ export class Escrow { ipfsClient: IPFSClient, viemClient: ViemClient, platformId: number, - chainId: NetworkEnum, chainConfig: ChainConfig ) { @@ -47,7 +44,6 @@ export class Escrow { this.platformID = platformId; this.ipfsClient = ipfsClient; this.viemClient = viemClient; - this.chainId = chainId; this.chainConfig = chainConfig; this.erc20 = new ERC20(this.ipfsClient, this.viemClient, this.platformID, this.chainConfig); } diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index 76e3c5f..0e9765d 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -17,6 +17,7 @@ import { IEscrow } from './escrow/types'; import { IService, Service } from './services'; import { IReview } from './reviews/types'; import { Review } from './reviews'; +import { isCustomChainConfig, isNetworkEnum } from './utils/typeguard'; /** * Main client for interacting with the TalentLayer protocol. @@ -31,8 +32,6 @@ export class TalentLayerClient { /** @hidden */ platformID: number; /** @hidden */ - chainId: NetworkEnum; - /** @hidden */ signatureApiUrl?: string; /** @hidden */ chainConfig: Config | CustomChainConfig; @@ -41,19 +40,28 @@ export class TalentLayerClient { constructor(config: TalentLayerClientConfig) { console.log('SDK: client initialising', config); this.platformID = config.platformId; - this.graphQlClient = new GraphQLClient(getGraphQLConfig(config.chainId)); + this.ipfsClient = new IPFSClient({ baseUrl: config.ipfsConfig.baseUrl, clientId: config.ipfsConfig.clientId, clientSecret: config.ipfsConfig.clientSecret, }); - this.chainId = config.chainId; this.signatureApiUrl = config?.signatureApiUrl; - this.chainConfig = getChainConfig(config.chainId); - if (config.customChainConfig) { + if (config?.chainId) { + this.chainConfig = getChainConfig(config.chainId); + } else if (config.customChainConfig) { + // if user has given custom chain config, that will take priority this.chainConfig = config.customChainConfig + } else { + throw Error('Atleast one of chainId or customChainConfig need to be provided') + } + + if (isNetworkEnum(this.chainConfig.networkId)) { + this.graphQlClient = new GraphQLClient(getGraphQLConfig(this.chainConfig.networkId)); + } else { + this.graphQlClient = new GraphQLClient({ subgraphUrl: this.chainConfig.subgraphUrl, chainId: this.chainConfig.networkId }); } this.viemClient = new ViemClient({ ...config.walletConfig, chainConfig: this.chainConfig }); @@ -162,7 +170,6 @@ export class TalentLayerClient { this.ipfsClient, this.viemClient, this.platformID, - this.chainId, this.chainConfig ); } diff --git a/packages/client/src/types/index.ts b/packages/client/src/types/index.ts index ee0f3c3..acb6bb2 100644 --- a/packages/client/src/types/index.ts +++ b/packages/client/src/types/index.ts @@ -61,7 +61,7 @@ export type ViemClientConfig = { }; export type TalentLayerClientConfig = { - chainId: NetworkEnum; + chainId?: NetworkEnum; ipfsConfig: IPFSClientConfig; walletConfig?: { rpcUrl?: string; diff --git a/packages/client/src/utils/typeguard.ts b/packages/client/src/utils/typeguard.ts index 591cff9..e42be22 100644 --- a/packages/client/src/utils/typeguard.ts +++ b/packages/client/src/utils/typeguard.ts @@ -1,4 +1,4 @@ -import { ChainConfig, CustomChainConfig } from "../types" +import { ChainConfig, CustomChainConfig, NetworkEnum } from "../types" // const isNecklace = (b: Accessory): b is Necklace => { // return (b as Necklace).kind !== undefined @@ -6,4 +6,8 @@ import { ChainConfig, CustomChainConfig } from "../types" export const isCustomChainConfig = (config: ChainConfig): config is CustomChainConfig => { return (config as CustomChainConfig).chainDefinition !== undefined; +} + +export const isNetworkEnum = (networkId: number): networkId is NetworkEnum => { + return Object.values(NetworkEnum).includes(networkId); } \ No newline at end of file From a0237051551be6bec11be2c973a0242a14c7657d Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Sat, 2 Dec 2023 13:03:00 +0000 Subject: [PATCH 31/40] Update Escrow ABI --- .../src/contracts/ABI/TalentLayerEscrow.json | 41 +------------------ 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/packages/client/src/contracts/ABI/TalentLayerEscrow.json b/packages/client/src/contracts/ABI/TalentLayerEscrow.json index 5bb842b..66c5dd9 100644 --- a/packages/client/src/contracts/ABI/TalentLayerEscrow.json +++ b/packages/client/src/contracts/ABI/TalentLayerEscrow.json @@ -371,43 +371,6 @@ "name": "Payment", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "_transactionId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "enum TalentLayerEscrowV1.PaymentType", - "name": "_paymentType", - "type": "uint8" - }, - { - "indexed": false, - "internalType": "address", - "name": "_token", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_serviceId", - "type": "uint256" - } - ], - "name": "Payment", - "type": "event" - }, { "anonymous": false, "inputs": [ @@ -1298,8 +1261,8 @@ "type": "function" } ], - "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b60805161501b62000120600039600081816114df0152818161151f015281816118e80152818161192801526119b7015261501b6000f3fe6080604052600436106101cd5760003560e01c80635a34257a116100f75780638b69fa0a11610095578063e308a09911610064578063e308a09914610523578063eb63612d14610543578063f2fde38b14610563578063f8c8765e1461058357600080fd5b80638b69fa0a146104a55780638da5cb5b146104c55780639dcc5daf146104e3578063ddd5e1b21461050357600080fd5b8063715018a6116100d1578063715018a6146104555780637b44cdb51461046a5780637e69b7b01461047d5780638456cb591461049057600080fd5b80635a34257a146103f45780635c975abb1461042a5780636e72b4521461044257600080fd5b80633659cfe61161016f5780633f4ba83a1161013e5780633f4ba83a1461036e5780634f1ef2861461038357806352d1902d14610396578063572b6c05146103ab57600080fd5b80633659cfe6146102ee5780633751d89c1461030e5780633a1121cd1461032e5780633ab4a6a41461034e57600080fd5b806315734fe7116101ab57806315734fe71461026b57806326d006681461027e5780632fbe3b03146102a0578063311a6c56146102ce57600080fd5b806306d6e63f146101d25780630a1a47d6146102105780630fa683d31461023e575b600080fd5b3480156101de57600080fd5b50610101546101f3906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021c57600080fd5b5061023061022b3660046140ea565b6105a3565b604051908152602001610207565b34801561024a57600080fd5b5061025e610259366004614107565b61070f565b604051610207919061419a565b610230610279366004614430565b610a5d565b34801561028a57600080fd5b5061029e6102993660046140ea565b611303565b005b3480156102ac57600080fd5b506102306102bb366004614107565b6101026020526000908152604090205481565b3480156102da57600080fd5b5061029e6102e93660046144a7565b611366565b3480156102fa57600080fd5b5061029e6103093660046140ea565b6114d5565b34801561031a57600080fd5b5061029e6103293660046140ea565b6115b4565b34801561033a57600080fd5b5061029e6103493660046144c9565b61160d565b34801561035a57600080fd5b5061029e610369366004614107565b611716565b34801561037a57600080fd5b5061029e6118cc565b61029e6103913660046144f5565b6118de565b3480156103a257600080fd5b506102306119aa565b3480156103b757600080fd5b506103e46103c63660046140ea565b6001600160a01b031660009081526065602052604090205460ff1690565b6040519015158152602001610207565b34801561040057600080fd5b506101015461041790600160a01b900461ffff1681565b60405161ffff9091168152602001610207565b34801561043657600080fd5b5060665460ff166103e4565b61029e610450366004614107565b611a5d565b34801561046157600080fd5b5061029e611cf6565b61029e610478366004614107565b611d08565b61029e61048b366004614107565b611f82565b34801561049c57600080fd5b5061029e61203a565b3480156104b157600080fd5b5061029e6104c0366004614559565b61204a565b3480156104d157600080fd5b506033546001600160a01b03166101f3565b3480156104ef57600080fd5b5061029e6104fe3660046144c9565b6123ad565b34801561050f57600080fd5b5061029e61051e3660046145a9565b61249b565b34801561052f57600080fd5b5061029e61053e3660046140ea565b6126af565b34801561054f57600080fd5b5061029e61055e3660046145e9565b6126da565b34801561056f57600080fd5b5061029e61057e3660046140ea565b612733565b34801561058f57600080fd5b5061029e61059e366004614606565b6127a9565b6000806105ae61292a565b9050806001600160a01b03166105cc6033546001600160a01b031690565b6001600160a01b0316036106165750506001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc602052604090205490565b61010054604051631847c06b60e01b81526001600160a01b0383811660048301526000921690631847c06b90602401602060405180830381865afa158015610662573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106869190614662565b6101005460405162f577a560e81b8152600481018390529192506001600160a01b03169063f577a5009060240160006040518083038186803b1580156106cb57600080fd5b505afa1580156106df573d6000803e3d6000fd5b50505060009182525060fd602090815260408083206001600160a01b039096168352949052929092205492915050565b6107a96040805161026081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290529061018082019081526020016000815260200160008152602001600081526020016000815260200160608152602001600081525090565b600082815260fc602090815260408083208151610260810183528154815260018201546001600160a01b039081169482019490945260028201548416928101929092526003810154831660608301526004808201546080840152600582015460a0840152600682015460c0840152600782015460e0840152600882015461ffff8082166101008601526201000082048116610120860152640100000000820416610140850152600160301b810490941661016084015291929091610180840191600160d01b900460ff169081111561088357610883614120565b600481111561089457610894614120565b815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d820180546108d09061467b565b80601f01602080910402602001604051908101604052809291908181526020018280546108fc9061467b565b80156109495780601f1061091e57610100808354040283529160200191610949565b820191906000526020600020905b81548152906001019060200180831161092c57829003601f168201915b50505050508152602001600e8201548152505090506109686101035490565b8151106109b55760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064015b60405180910390fd5b60006109bf61292a565b905081602001516001600160a01b0316816001600160a01b031614806109fa575081604001516001600160a01b0316816001600160a01b0316145b610a565760405162461bcd60e51b815260206004820152602760248201527f596f7520617265206e6f742072656c6174656420746f2074686973207472616e60448201526639b0b1ba34b7b760c91b60648201526084016109ac565b5092915050565b6000610a67612939565b60fe5460405163353bb87f60e21b8152600481018790526024810186905260009182916001600160a01b039091169063d4eee1fc90604401600060405180830381865afa158015610abc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ae491908101906147ab565b60ff54602083810151908301516040516303ef723760e61b81526004810192909252602482015292945090925060009182916001600160a01b03169063fbdc8dc0906044016040805180830381865afa158015610b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b699190614876565b6101005460a0870151604051630b7a459360e31b815260048101919091529294509092506000916001600160a01b0390911690635bd22c9890602401600060405180830381865afa158015610bc2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610bea91908101906148b0565b9050600084608001518660a0015103610c035781610c80565b610100546080860151604051630b7a459360e31b81526001600160a01b0390921691635bd22c9891610c3b9160040190815260200190565b600060405180830381865afa158015610c58573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c8091908101906148b0565b90506000610c9b86606001518460600151846080015161297f565b60408701519091506001600160a01b0316610cf957803414610cf45760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016109ac565b610d3c565b3415610d3c5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016109ac565b846001600160a01b0316610d4e61292a565b6001600160a01b031614610d745760405162461bcd60e51b81526004016109ac906149dc565b8a866020015114610dbf5760405162461bcd60e51b8152602060048201526015602482015274125b98dbdc9c9958dd081c1c9bdc1bdcd85b081251605a1b60448201526064016109ac565b428660c001511015610e065760405162461bcd60e51b815260206004820152601060248201526f141c9bdc1bdcd85b08195e1c1a5c995960821b60448201526064016109ac565b600087516004811115610e1b57610e1b614120565b14610e685760405162461bcd60e51b815260206004820152601760248201527f5365727669636520737461747573206e6f74206f70656e00000000000000000060448201526064016109ac565b600086516001811115610e7d57610e7d614120565b14610eca5760405162461bcd60e51b815260206004820152601b60248201527f50726f706f73616c20737461747573206e6f742070656e64696e67000000000060448201526064016109ac565b8951602e14610f095760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b60448201526064016109ac565b88604051602001610f1a9190614a03565b604051602081830303815290604052805190602001208660a00151604051602001610f459190614a03565b6040516020818303038152906040528051906020012014610fa85760405162461bcd60e51b815260206004820152601c60248201527f50726f706f73616c206461746155726920686173206368616e6765640000000060448201526064016109ac565b6000610fb46101035490565b9050604051806102600160405280828152602001876001600160a01b03168152602001866001600160a01b0316815260200188604001516001600160a01b0316815260200188606001518152602001600081526020018e81526020018d815260200161010160149054906101000a900461ffff1661ffff168152602001856060015161ffff168152602001846080015161ffff1681526020018560e001516001600160a01b031681526020016000600481111561107357611073614120565b8152600060208083018290526040808401839052606080850184905242608080870191909152610100808c015160a080890191909152610120808e015160c0998a01528a885260fc87529685902089518155958901516001870180546001600160a01b039283166001600160a01b031991821617909155958a01516002880180549183169188169190911790559389015160038701805491861691909616179094559087015160048086019190915592870151600585015594860151600684015560e086015160078401559385015160088301805494870151610140880151610160890151909716600160301b026601000000000000600160d01b031961ffff9889166401000000000216640100000000600160d01b0319928916620100000263ffffffff19909816989094169790971795909517949094161793909317808355610180850151919391929160ff60d01b1990911690600160d01b9084908111156111e0576111e0614120565b02179055506101a082015160098201556101c0820151600a8201556101e0820151600b820155610200820151600c820155610220820151600d8201906112269082614a65565b5061024082015181600e015590505061124461010380546001019055565b60fe546040516353eaf57560e11b8152600481018f9052602481018e9052604481018390526001600160a01b039091169063a7d5eaea90606401600060405180830381600087803b15801561129857600080fd5b505af11580156112ac573d6000803e3d6000fd5b5050505060408701516001600160a01b0316156112dd5760408701516112dd906001600160a01b03168730856129eb565b6112f188602001518860200151838e612a4b565b9750505050505050505b949350505050565b61130b612b66565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b600061137061292a565b6000848152610102602090815260408083205480845260fc909252909120600881015492935090916001600160a01b03808516600160301b90920416146114035760405162461bcd60e51b815260206004820152602160248201527f5468652063616c6c6572206d757374206265207468652061726269747261746f6044820152603960f91b60648201526084016109ac565b60036008820154600160d01b900460ff16600481111561142557611425614120565b146114805760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652068617320616c7265616479206265656e207265736044820152641bdb1d995960da1b60648201526084016109ac565b84836001600160a01b03167f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e75622276866040516114bc91815260200190565b60405180910390a36114ce8285612bdf565b5050505050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361151d5760405162461bcd60e51b81526004016109ac90614b25565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611566600080516020614f7f833981519152546001600160a01b031690565b6001600160a01b03161461158c5760405162461bcd60e51b81526004016109ac90614b71565b61159581612e69565b604080516000808252602082019092526115b191839190612e71565b50565b6115bc612b66565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee6910161135b565b611615612939565b60ff5483906001600160a01b0316632fa117e58261163161292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561167b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169f9190614bbd565b6116bb5760405162461bcd60e51b81526004016109ac90614bdf565b6116c88360008685612fdc565b600083815260fc60205260408120600481018054919285926116eb908490614c24565b92505081905550828160050160008282546117069190614c37565b909155506114ce905084846132c7565b600081815260fc60205260409020600e810154600c8201546117389042614c24565b10156117865760405162461bcd60e51b815260206004820152601f60248201527f54696d656f75742074696d6520686173206e6f7420706173736564207965740060448201526064016109ac565b60016008820154600160d01b900460ff1660048111156117a8576117a8614120565b0361182b57600a8101541561181c57600a81018054600091829055600183015460405191926001600160a01b0390911691839181818185875af1925050503d8060008114611812576040519150601f19603f3d011682016040523d82523d6000602084013e611817565b606091505b505050505b611827826002612bdf565b5050565b60026008820154600160d01b900460ff16600481111561184d5761184d614120565b0361182757600b810154156118c157600b81018054600091829055600283015460405191926001600160a01b0390911691839181818185875af1925050503d80600081146118b7576040519150601f19603f3d011682016040523d82523d6000602084013e6118bc565b606091505b505050505b611827826001612bdf565b6118d4612b66565b6118dc61330c565b565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036119265760405162461bcd60e51b81526004016109ac90614b25565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661196f600080516020614f7f833981519152546001600160a01b031690565b6001600160a01b0316146119955760405162461bcd60e51b81526004016109ac90614b71565b61199e82612e69565b61182782826001612e71565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a4a5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016109ac565b50600080516020614f7f83398151915290565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611a9c5760405162461bcd60e51b81526004016109ac90614c4a565b60036008820154600160d01b900460ff166004811115611abe57611abe614120565b10611adb5760405162461bcd60e51b81526004016109ac90614c76565b60028101546001600160a01b0316611af161292a565b6001600160a01b031614611b475760405162461bcd60e51b815260206004820152601f60248201527f5468652063616c6c6572206d757374206265207468652072656365697665720060448201526064016109ac565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611b8490600d860190600401614d66565b602060405180830381865afa158015611ba1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc59190614662565b90503482600b016000828254611bdb9190614c37565b9091555050600b8201548114611c525760405162461bcd60e51b815260206004820152603660248201527f54686520726563656976657220666565206d75737420626520657175616c20746044820152751bc81d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60521b60648201526084016109ac565b42600c8301556040518390600080516020614f9f83398151915290611c7e906000906001903490614d89565b60405180910390a28082600a01541015611ce75760088201805460ff60d01b1916600160d01b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611cda90600090614db3565b60405180910390a2505050565b611cf18382613364565b505050565b611cfe612b66565b6118dc60006135b7565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611d475760405162461bcd60e51b81526004016109ac90614c4a565b60036008820154600160d01b900460ff166004811115611d6957611d69614120565b10611d865760405162461bcd60e51b81526004016109ac90614c76565b60018101546001600160a01b0316611d9c61292a565b6001600160a01b031614611df25760405162461bcd60e51b815260206004820152601d60248201527f5468652063616c6c6572206d757374206265207468652073656e64657200000060448201526064016109ac565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611e2f90600d860190600401614d66565b602060405180830381865afa158015611e4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e709190614662565b90503482600a016000828254611e869190614c37565b9091555050600a8201548114611efb5760405162461bcd60e51b815260206004820152603460248201527f5468652073656e64657220666565206d75737420626520657175616c20746f206044820152731d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60621b60648201526084016109ac565b42600c8301556040518390600080516020614f9f83398151915290611f269060009081903490614d89565b60405180910390a28082600b01541015611ce75760088201805460ff60d01b1916600160d11b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611cda90600190614db3565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611fc15760405162461bcd60e51b81526004016109ac90614c4a565b6008810154600982015460405163093225f160e31b8152600160301b9092046001600160a01b0316916349912f889134916120049190600d870190600401614dc6565b6000604051808303818588803b15801561201d57600080fd5b505af1158015612031573d6000803e3d6000fd5b50505050505050565b612042612b66565b6118dc613609565b60ff5483906001600160a01b0316632fa117e58261206661292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156120b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d49190614bbd565b6120f05760405162461bcd60e51b81526004016109ac90614bdf565b8151602e1461212f5760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b60448201526064016109ac565b600083815260fc602052604090206008810154600160301b90046001600160a01b031661216e5760405162461bcd60e51b81526004016109ac90614c4a565b60ff546040516331a9108f60e11b8152600481018790526000916001600160a01b031690636352211e90602401602060405180830381865afa1580156121b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121dc9190614ddf565b60018301549091506001600160a01b038083169116148061220c575060028201546001600160a01b038281169116145b612280576040805162461bcd60e51b81526020600482015260248101919091527f5468652063616c6c6572206d757374206265207468652073656e646572206f7260448201527f20746865207265636569766572206f722074686569722064656c65676174657360648201526084016109ac565b60046008830154600160d01b900460ff1660048111156122a2576122a2614120565b106123095760405162461bcd60e51b815260206004820152603160248201527f4d757374206e6f742073656e642065766964656e6365206966207468652064696044820152701cdc1d5d19481a5cc81c995cdbdb1d9959607a1b60648201526084016109ac565b806001600160a01b0316858360080160069054906101000a90046001600160a01b03166001600160a01b03167fdccf2f8b2cc26eafcd61905cba744cff4b81d14740725f6376390dc6298a6a3c876040516123649190614dfc565b60405180910390a485857fd998ce0f89c38b0f93256f0b843a404a3a3c5055b75265623f7cb9c369a1dd628660405161239d9190614dfc565b60405180910390a3505050505050565b6123b5612939565b60ff5483906001600160a01b0316632fa117e5826123d161292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561241b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243f9190614bbd565b61245b5760405162461bcd60e51b81526004016109ac90614bdf565b6124688360018685612fdc565b600083815260fc602052604081206004810180549192859261248b908490614c24565b909155506114ce90508484613647565b6124a3612939565b60006124ad61292a565b6001600160a01b03166124c86033546001600160a01b031690565b6001600160a01b0316036125075782156124f45760405162461bcd60e51b81526004016109ac906149dc565b50610101546001600160a01b03166125d4565b6101005460405162f577a560e81b8152600481018590526001600160a01b039091169063f577a5009060240160006040518083038186803b15801561254b57600080fd5b505afa15801561255f573d6000803e3d6000fd5b5050610100546040516331a9108f60e11b8152600481018790526001600160a01b039091169250636352211e9150602401602060405180830381865afa1580156125ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d19190614ddf565b90505b600083815260fd602090815260408083206001600160a01b0386168452909152902054806126375760405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b60448201526064016109ac565b600084815260fd602090815260408083206001600160a01b03871684529091528120556126658284836136ad565b60408051858152602081018390526001600160a01b038516917f2227733fc4c8a9034cb58087dcf6995128b9c0233b038b03366aaf30c92b92d6910160405180910390a250505050565b6126b7612b66565b61010180546001600160a01b0319166001600160a01b0392909216919091179055565b6126e2612b66565b610101805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f8339189e972f7fba792126e752aa8485af08710bce4a041c5bc3f9858acd71309060200161135b565b61273b612b66565b6001600160a01b0381166127a05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109ac565b6115b1816135b7565b600054610100900460ff16158080156127c95750600054600160ff909116105b806127e35750303b1580156127e3575060005460ff166001145b6128465760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016109ac565b6000805460ff191660011790558015612869576000805461ff0019166101001790555b612871613787565b6128796137b6565b60fe80546001600160a01b038088166001600160a01b03199283161790925560ff805487841690831617905561010080548684169083161790556101018054928516929091169190911790556128d461010380546001019055565b6128de60646126da565b80156114ce576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b60006129346137dd565b905090565b60665460ff16156118dc5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016109ac565b600061271061299261ffff841686614e0f565b6129a061ffff861687614e0f565b610101546129b990600160a01b900461ffff1688614e0f565b6129c39190614c37565b6129cd9190614c37565b6129d79190614e26565b6129e19085614c37565b90505b9392505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612a45908590613816565b50505050565b600060fc600084815260200190815260200160002090507f8b4f0e94aa0aee74c276abd2d92a5e2737a493b055e19d5b2d4c0ac573242a158386868460030160009054906101000a90046001600160a01b031685600401548660060154876007015461010160149054906101000a900461ffff168960080160029054906101000a900461ffff168a60080160049054906101000a900461ffff168b60080160069054906101000a90046001600160a01b03168c600d018d600e0154604051612b1f9d9c9b9a99989796959493929190614e48565b60405180910390a1827f61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d83604051612b579190614dfc565b60405180910390a25050505050565b612b6e61292a565b6001600160a01b0316612b896033546001600160a01b031690565b6001600160a01b0316146118dc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ac565b600082815260fc602052604090206002821115612c2f5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c69642072756c696e6760901b60448201526064016109ac565b60018101546002820154600483018054600a85018054600b87018054600095869055928590559390935560088601805460ff60d01b1916600160d21b1790556001600160a01b0394851694909316929091906000198701612cea576040516001600160a01b038616908390600081818185875af1925050503d8060008114612cd3576040519150601f19603f3d011682016040523d82523d6000602084013e612cd8565b606091505b505050612ce58884613647565b612e25565b6001198701612d4e576040516001600160a01b038516908290600081818185875af1925050503d8060008114612d3c576040519150601f19603f3d011682016040523d82523d6000602084013e612d41565b606091505b505050612ce588846132c7565b6000612d5b600284614e26565b90506000612d6a600286614e26565b9050612d768a82613647565b612d808a826132c7565b6040516001600160a01b038816908390600081818185875af1925050503d8060008114612dc9576040519150601f19603f3d011682016040523d82523d6000602084013e612dce565b606091505b50506040516001600160a01b03881691508390600081818185875af1925050503d8060008114612e1a576040519150601f19603f3d011682016040523d82523d6000602084013e612e1f565b606091505b50505050505b877f76b363d70472d47d20e4119f3625c05ed37ca51b1d9e1cd8b87d8c20530640f388604051612e5791815260200190565b60405180910390a25050505050505050565b6115b1612b66565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612ea457611cf1836138e8565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612efe575060408051601f3d908101601f19168201909252612efb91810190614662565b60015b612f615760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016109ac565b600080516020614f7f8339815191528114612fd05760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016109ac565b50611cf1838383613984565b600084815260fc6020526040812090846001811115612ffd57612ffd614120565b036130a35760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa15801561304b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306f9190614ddf565b60018201546001600160a01b0390811691161461309e5760405162461bcd60e51b81526004016109ac906149dc565b613158565b60018460018111156130b7576130b7614120565b036131585760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa158015613105573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131299190614ddf565b60028201546001600160a01b039081169116146131585760405162461bcd60e51b81526004016109ac906149dc565b610103548154106131a45760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064016109ac565b60006008820154600160d01b900460ff1660048111156131c6576131c6614120565b146132215760405162461bcd60e51b815260206004820152602560248201527f546865207472616e73616374696f6e2073686f756c646e2774206265206469736044820152641c1d5d195960da1b60648201526084016109ac565b818160040154101561326a5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b60448201526064016109ac565b6127108210158061328a57506127108210801561328a5750806004015482145b6114ce5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016109ac565b6132d182826139a9565b600082815260fc6020526040902060028101546003820154613300916001600160a01b039081169116846136ad565b611cf183600084613c57565b613314613d7d565b6066805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61334761292a565b6040516001600160a01b03909116815260200160405180910390a1565b600082815260fc60205260409081902060088101805460ff60d01b1916600360d01b1790819055915163c13517e160e01b81529091600160301b90046001600160a01b031690819063c13517e19085906133c890600290600d880190600401614ed6565b60206040518083038185885af11580156133e6573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061340b9190614662565b600983018181556000918252610102602090815260409283902087905590548251878152918201879052916001600160a01b038416917f74baab670a4015ab2f1b467c5252a96141a2573f2908e58a92081e80d3cfde3d910160405180910390a38282600a015411156135175760008383600a015461348a9190614c24565b600a840185905560018401546040519192506001600160a01b0316908290600081818185875af1925050503d80600081146134e1576040519150601f19603f3d011682016040523d82523d6000602084013e6134e6565b606091505b50505084600080516020614f9f833981519152600160003460405161350d93929190614d89565b60405180910390a2505b8282600b01541115612a455760008383600b01546135359190614c24565b600b840185905560028401546040519192506001600160a01b0316908290600081818185875af1925050503d806000811461358c576040519150601f19603f3d011682016040523d82523d6000602084013e613591565b606091505b50505084600080516020614f9f83398151915260018034604051612b5793929190614d89565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b613611612939565b6066805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861334761292a565b600082815260fc60205260408120600881015490919061367d90849061ffff62010000820481169164010000000090041661297f565b600183015460038401549192506136a1916001600160a01b039182169116836136ad565b612a4584600185613c57565b6001600160a01b038216600003613714576040516001600160a01b038416908290600081818185875af1925050503d8060008114613707576040519150601f19603f3d011682016040523d82523d6000602084013e61370c565b606091505b505050505050565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb906044016020604051808303816000875af1158015613763573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a459190614bbd565b600054610100900460ff166137ae5760405162461bcd60e51b81526004016109ac90614ef2565b6118dc613dc6565b600054610100900460ff166118dc5760405162461bcd60e51b81526004016109ac90614ef2565b6000601436108015906137ff57503360009081526065602052604090205460ff165b15613811575060131936013560601c90565b503390565b600061386b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613dfd9092919063ffffffff16565b805190915015611cf157808060200190518101906138899190614bbd565b611cf15760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109ac565b6001600160a01b0381163b6139555760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016109ac565b600080516020614f7f83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61398d83613e0c565b60008251118061399a5750805b15611cf157612a458383613e4c565b600082815260fc602052604080822060fe5460068201546007830154935163353bb87f60e21b81526004810191909152602481019390935290929182916001600160a01b03169063d4eee1fc90604401600060405180830381865afa158015613a16573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613a3e91908101906147ab565b60a0820151608082015160088701549395509193509160009061271090613a6a90899061ffff16614e0f565b613a749190614e26565b600887015490915060009061271090613a98908a9062010000900461ffff16614e0f565b613aa29190614e26565b600888015490915060009061271090613ac8908b90640100000000900461ffff16614e0f565b613ad29190614e26565b60038901546001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc6020526040812080549293508592909190613b22908490614c37565b9091555050600085815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054849290613b5d908490614c37565b9091555050600084815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054839290613b98908490614c37565b90915550506003880154600689015460408051888152602081019290925281018490526001600160a01b03909116907f17c48ab8e1617182f35ae77fd7da7f4e15dedf7018aa371a4481c20c790b65469060600160405180910390a26003880154600689015460408051878152602081019290925281018490526001600160a01b03909116907f3476ed3eea2cdac584273bc8830824c8ca42ca2a99e9f144a87a1cdbbf9dd15a9060600160405180910390a250505050505050505050565b600083815260fc6020526040908190208054600382015460068301546007840154945193947ff3afebb51c3c2b45151cf0572b3d287505cf6ecea01df5f222c1d8cf0159f22794613cb8949389936001600160a01b03909116928992614f3d565b60405180910390a18060040154600003612a455760fe5460068201546005830154604051635ab9ae0f60e11b8152600481019290925260248201526001600160a01b039091169063b5735c1e90604401600060405180830381600087803b158015613d2257600080fd5b505af1158015613d36573d6000803e3d6000fd5b505050507f6bef1b5e95b741d6e665eb9b5c2d3e1203c46a771451055a9d41e0b8ff4510b78160060154604051613d6f91815260200190565b60405180910390a150505050565b60665460ff166118dc5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016109ac565b600054610100900460ff16613ded5760405162461bcd60e51b81526004016109ac90614ef2565b6118dc613df861292a565b6135b7565b60606129e18484600085613f42565b613e15816138e8565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b613eb45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016109ac565b600080846001600160a01b031684604051613ecf9190614a03565b600060405180830381855af49150503d8060008114613f0a576040519150601f19603f3d011682016040523d82523d6000602084013e613f0f565b606091505b5091509150613f378282604051806060016040528060278152602001614fbf6027913961401d565b925050505b92915050565b606082471015613fa35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016109ac565b600080866001600160a01b03168587604051613fbf9190614a03565b60006040518083038185875af1925050503d8060008114613ffc576040519150601f19603f3d011682016040523d82523d6000602084013e614001565b606091505b509150915061401287838387614036565b979650505050505050565b6060831561402c5750816129e4565b6129e483836140ab565b606083156140a557825160000361409e576001600160a01b0385163b61409e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109ac565b50816112fb565b6112fb83835b8151156140bb5781518083602001fd5b8060405162461bcd60e51b81526004016109ac9190614dfc565b6001600160a01b03811681146115b157600080fd5b6000602082840312156140fc57600080fd5b81356129e4816140d5565b60006020828403121561411957600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b6005811061414657614146614120565b9052565b60005b8381101561416557818101518382015260200161414d565b50506000910152565b6000815180845261418681602086016020860161414a565b601f01601f19169290920160200192915050565b6020815281516020820152600060208301516141c160408401826001600160a01b03169052565b5060408301516001600160a01b03811660608401525060608301516001600160a01b038116608084015250608083015160a083015260a083015160c083015260c083015160e083015260e08301516101008181850152808501519150506101206142308185018361ffff169052565b84015190506101406142478482018361ffff169052565b840151905061016061425e8482018361ffff169052565b840151905061018061427a848201836001600160a01b03169052565b84015190506101a061428e84820183614136565b8401516101c0848101919091528401516101e0808501919091528401516102008085019190915284015161022080850191909152840151610260610240808601829052919250906142e361028086018461416e565b9501519301929092525090919050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff8111828210171561432c5761432c6142f3565b60405290565b60405160c0810167ffffffffffffffff8111828210171561432c5761432c6142f3565b604051610160810167ffffffffffffffff8111828210171561432c5761432c6142f3565b604051601f8201601f1916810167ffffffffffffffff811182821017156143a2576143a26142f3565b604052919050565b600067ffffffffffffffff8211156143c4576143c46142f3565b50601f01601f191660200190565b60006143e56143e0846143aa565b614379565b90508281528383830111156143f957600080fd5b828260208301376000602084830101529392505050565b600082601f83011261442157600080fd5b6129e4838335602085016143d2565b6000806000806080858703121561444657600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561446c57600080fd5b61447888838901614410565b9350606087013591508082111561448e57600080fd5b5061449b87828801614410565b91505092959194509250565b600080604083850312156144ba57600080fd5b50508035926020909101359150565b6000806000606084860312156144de57600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561450857600080fd5b8235614513816140d5565b9150602083013567ffffffffffffffff81111561452f57600080fd5b8301601f8101851361454057600080fd5b61454f858235602084016143d2565b9150509250929050565b60008060006060848603121561456e57600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561459357600080fd5b61459f86828701614410565b9150509250925092565b600080604083850312156145bc57600080fd5b8235915060208301356145ce816140d5565b809150509250929050565b61ffff811681146115b157600080fd5b6000602082840312156145fb57600080fd5b81356129e4816145d9565b6000806000806080858703121561461c57600080fd5b8435614627816140d5565b93506020850135614637816140d5565b92506040850135614647816140d5565b91506060850135614657816140d5565b939692955090935050565b60006020828403121561467457600080fd5b5051919050565b600181811c9082168061468f57607f821691505b6020821081036146af57634e487b7160e01b600052602260045260246000fd5b50919050565b600082601f8301126146c657600080fd5b81516146d46143e0826143aa565b8181528460208386010111156146e957600080fd5b6112fb82602083016020870161414a565b80516002811061470957600080fd5b919050565b8051614709816140d5565b600060e0828403121561472b57600080fd5b614733614309565b905061473e826146fa565b8152602082015160208201526147566040830161470e565b6040820152606082015160608201526080820151608082015260a082015167ffffffffffffffff81111561478957600080fd5b614795848285016146b5565b60a08301525060c082015160c082015292915050565b600080604083850312156147be57600080fd5b825167ffffffffffffffff808211156147d657600080fd5b9084019060c082870312156147ea57600080fd5b6147f2614332565b82516005811061480157600080fd5b80825250602083015160208201526040830151604082015260608301518281111561482b57600080fd5b614837888286016146b5565b6060830152506080830151608082015260a083015160a082015280945050602085015191508082111561486957600080fd5b5061454f85828601614719565b6000806040838503121561488957600080fd5b8251614894816140d5565b60208401519092506145ce816140d5565b8051614709816145d9565b6000602082840312156148c257600080fd5b815167ffffffffffffffff808211156148da57600080fd5b9083019061016082860312156148ef57600080fd5b6148f7614355565b8251815260208301518281111561490d57600080fd5b614919878286016146b5565b60208301525060408301518281111561493157600080fd5b61493d878286016146b5565b60408301525061494f606084016148a5565b6060820152614960608084016148a5565b608082015260a083015160a082015260c083015160c082015261498560e0840161470e565b60e0820152610100808401518381111561499e57600080fd5b6149aa888287016146b5565b8284015250506101209150818301518282015261014091506149cd82840161470e565b91810191909152949350505050565b6020808252600d908201526c1058d8d95cdcc819195b9a5959609a1b604082015260600190565b60008251614a1581846020870161414a565b9190910192915050565b601f821115611cf157600081815260208120601f850160051c81016020861015614a465750805b601f850160051c820191505b8181101561370c57828155600101614a52565b815167ffffffffffffffff811115614a7f57614a7f6142f3565b614a9381614a8d845461467b565b84614a1f565b602080601f831160018114614ac85760008415614ab05750858301515b600019600386901b1c1916600185901b17855561370c565b600085815260208120601f198616915b82811015614af757888601518255948401946001909101908401614ad8565b5085821015614b155787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215614bcf57600080fd5b815180151581146129e457600080fd5b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b81810381811115613f3c57613f3c614c0e565b80820180821115613f3c57613f3c614c0e565b602080825260129082015271105c989a5d1c985d1bdc881b9bdd081cd95d60721b604082015260600190565b6020808252604d908201527f446973707574652068617320616c7265616479206265656e206372656174656460408201527f206f72206265636175736520746865207472616e73616374696f6e206861732060608201526c1899595b88195e1958dd5d1959609a1b608082015260a00190565b60008154614cf68161467b565b808552602060018381168015614d135760018114614d2d57614d5b565b60ff1985168884015283151560051b880183019550614d5b565b866000528260002060005b85811015614d535781548a8201860152908301908401614d38565b890184019650505b505050505092915050565b6020815260006129e46020830184614ce9565b600281106115b1576115b1614120565b60608101614d9685614d79565b848252614da284614d79565b602082019390935260400152919050565b60208101614dc083614d79565b91905290565b8281526040602082015260006129e16040830184614ce9565b600060208284031215614df157600080fd5b81516129e4816140d5565b6020815260006129e4602083018461416e565b8082028115828204841417613f3c57613f3c614c0e565b600082614e4357634e487b7160e01b600052601260045260246000fd5b500490565b8d8152602081018d9052604081018c90526001600160a01b038b81166060830152608082018b905260a082018a905260c0820189905261ffff88811660e08401528781166101008401528616610120830152841661014082015260006101a080610160840152614eba81840186614ce9565b915050826101808301529e9d5050505050505050505050505050565b60ff831681526040602082015260006129e16040830184614ce9565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b86815260c08101614f4d87614d79565b60208201969096526001600160a01b039490941660408501526060840192909252608083015260a09091015291905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc73e533bc8a993eccbc1023beebad0020f6b6c3639f83062f00fc194b4d1172ba416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a7f8bc736209ed86b0a75451b8ebeb8112ce6d951fbc6a029e99724cff4fa1e364736f6c63430008110033", - "deployedBytecode": "0x6080604052600436106101cd5760003560e01c80635a34257a116100f75780638b69fa0a11610095578063e308a09911610064578063e308a09914610523578063eb63612d14610543578063f2fde38b14610563578063f8c8765e1461058357600080fd5b80638b69fa0a146104a55780638da5cb5b146104c55780639dcc5daf146104e3578063ddd5e1b21461050357600080fd5b8063715018a6116100d1578063715018a6146104555780637b44cdb51461046a5780637e69b7b01461047d5780638456cb591461049057600080fd5b80635a34257a146103f45780635c975abb1461042a5780636e72b4521461044257600080fd5b80633659cfe61161016f5780633f4ba83a1161013e5780633f4ba83a1461036e5780634f1ef2861461038357806352d1902d14610396578063572b6c05146103ab57600080fd5b80633659cfe6146102ee5780633751d89c1461030e5780633a1121cd1461032e5780633ab4a6a41461034e57600080fd5b806315734fe7116101ab57806315734fe71461026b57806326d006681461027e5780632fbe3b03146102a0578063311a6c56146102ce57600080fd5b806306d6e63f146101d25780630a1a47d6146102105780630fa683d31461023e575b600080fd5b3480156101de57600080fd5b50610101546101f3906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021c57600080fd5b5061023061022b3660046140ea565b6105a3565b604051908152602001610207565b34801561024a57600080fd5b5061025e610259366004614107565b61070f565b604051610207919061419a565b610230610279366004614430565b610a5d565b34801561028a57600080fd5b5061029e6102993660046140ea565b611303565b005b3480156102ac57600080fd5b506102306102bb366004614107565b6101026020526000908152604090205481565b3480156102da57600080fd5b5061029e6102e93660046144a7565b611366565b3480156102fa57600080fd5b5061029e6103093660046140ea565b6114d5565b34801561031a57600080fd5b5061029e6103293660046140ea565b6115b4565b34801561033a57600080fd5b5061029e6103493660046144c9565b61160d565b34801561035a57600080fd5b5061029e610369366004614107565b611716565b34801561037a57600080fd5b5061029e6118cc565b61029e6103913660046144f5565b6118de565b3480156103a257600080fd5b506102306119aa565b3480156103b757600080fd5b506103e46103c63660046140ea565b6001600160a01b031660009081526065602052604090205460ff1690565b6040519015158152602001610207565b34801561040057600080fd5b506101015461041790600160a01b900461ffff1681565b60405161ffff9091168152602001610207565b34801561043657600080fd5b5060665460ff166103e4565b61029e610450366004614107565b611a5d565b34801561046157600080fd5b5061029e611cf6565b61029e610478366004614107565b611d08565b61029e61048b366004614107565b611f82565b34801561049c57600080fd5b5061029e61203a565b3480156104b157600080fd5b5061029e6104c0366004614559565b61204a565b3480156104d157600080fd5b506033546001600160a01b03166101f3565b3480156104ef57600080fd5b5061029e6104fe3660046144c9565b6123ad565b34801561050f57600080fd5b5061029e61051e3660046145a9565b61249b565b34801561052f57600080fd5b5061029e61053e3660046140ea565b6126af565b34801561054f57600080fd5b5061029e61055e3660046145e9565b6126da565b34801561056f57600080fd5b5061029e61057e3660046140ea565b612733565b34801561058f57600080fd5b5061029e61059e366004614606565b6127a9565b6000806105ae61292a565b9050806001600160a01b03166105cc6033546001600160a01b031690565b6001600160a01b0316036106165750506001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc602052604090205490565b61010054604051631847c06b60e01b81526001600160a01b0383811660048301526000921690631847c06b90602401602060405180830381865afa158015610662573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106869190614662565b6101005460405162f577a560e81b8152600481018390529192506001600160a01b03169063f577a5009060240160006040518083038186803b1580156106cb57600080fd5b505afa1580156106df573d6000803e3d6000fd5b50505060009182525060fd602090815260408083206001600160a01b039096168352949052929092205492915050565b6107a96040805161026081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290529061018082019081526020016000815260200160008152602001600081526020016000815260200160608152602001600081525090565b600082815260fc602090815260408083208151610260810183528154815260018201546001600160a01b039081169482019490945260028201548416928101929092526003810154831660608301526004808201546080840152600582015460a0840152600682015460c0840152600782015460e0840152600882015461ffff8082166101008601526201000082048116610120860152640100000000820416610140850152600160301b810490941661016084015291929091610180840191600160d01b900460ff169081111561088357610883614120565b600481111561089457610894614120565b815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d820180546108d09061467b565b80601f01602080910402602001604051908101604052809291908181526020018280546108fc9061467b565b80156109495780601f1061091e57610100808354040283529160200191610949565b820191906000526020600020905b81548152906001019060200180831161092c57829003601f168201915b50505050508152602001600e8201548152505090506109686101035490565b8151106109b55760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064015b60405180910390fd5b60006109bf61292a565b905081602001516001600160a01b0316816001600160a01b031614806109fa575081604001516001600160a01b0316816001600160a01b0316145b610a565760405162461bcd60e51b815260206004820152602760248201527f596f7520617265206e6f742072656c6174656420746f2074686973207472616e60448201526639b0b1ba34b7b760c91b60648201526084016109ac565b5092915050565b6000610a67612939565b60fe5460405163353bb87f60e21b8152600481018790526024810186905260009182916001600160a01b039091169063d4eee1fc90604401600060405180830381865afa158015610abc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ae491908101906147ab565b60ff54602083810151908301516040516303ef723760e61b81526004810192909252602482015292945090925060009182916001600160a01b03169063fbdc8dc0906044016040805180830381865afa158015610b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b699190614876565b6101005460a0870151604051630b7a459360e31b815260048101919091529294509092506000916001600160a01b0390911690635bd22c9890602401600060405180830381865afa158015610bc2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610bea91908101906148b0565b9050600084608001518660a0015103610c035781610c80565b610100546080860151604051630b7a459360e31b81526001600160a01b0390921691635bd22c9891610c3b9160040190815260200190565b600060405180830381865afa158015610c58573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c8091908101906148b0565b90506000610c9b86606001518460600151846080015161297f565b60408701519091506001600160a01b0316610cf957803414610cf45760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016109ac565b610d3c565b3415610d3c5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016109ac565b846001600160a01b0316610d4e61292a565b6001600160a01b031614610d745760405162461bcd60e51b81526004016109ac906149dc565b8a866020015114610dbf5760405162461bcd60e51b8152602060048201526015602482015274125b98dbdc9c9958dd081c1c9bdc1bdcd85b081251605a1b60448201526064016109ac565b428660c001511015610e065760405162461bcd60e51b815260206004820152601060248201526f141c9bdc1bdcd85b08195e1c1a5c995960821b60448201526064016109ac565b600087516004811115610e1b57610e1b614120565b14610e685760405162461bcd60e51b815260206004820152601760248201527f5365727669636520737461747573206e6f74206f70656e00000000000000000060448201526064016109ac565b600086516001811115610e7d57610e7d614120565b14610eca5760405162461bcd60e51b815260206004820152601b60248201527f50726f706f73616c20737461747573206e6f742070656e64696e67000000000060448201526064016109ac565b8951602e14610f095760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b60448201526064016109ac565b88604051602001610f1a9190614a03565b604051602081830303815290604052805190602001208660a00151604051602001610f459190614a03565b6040516020818303038152906040528051906020012014610fa85760405162461bcd60e51b815260206004820152601c60248201527f50726f706f73616c206461746155726920686173206368616e6765640000000060448201526064016109ac565b6000610fb46101035490565b9050604051806102600160405280828152602001876001600160a01b03168152602001866001600160a01b0316815260200188604001516001600160a01b0316815260200188606001518152602001600081526020018e81526020018d815260200161010160149054906101000a900461ffff1661ffff168152602001856060015161ffff168152602001846080015161ffff1681526020018560e001516001600160a01b031681526020016000600481111561107357611073614120565b8152600060208083018290526040808401839052606080850184905242608080870191909152610100808c015160a080890191909152610120808e015160c0998a01528a885260fc87529685902089518155958901516001870180546001600160a01b039283166001600160a01b031991821617909155958a01516002880180549183169188169190911790559389015160038701805491861691909616179094559087015160048086019190915592870151600585015594860151600684015560e086015160078401559385015160088301805494870151610140880151610160890151909716600160301b026601000000000000600160d01b031961ffff9889166401000000000216640100000000600160d01b0319928916620100000263ffffffff19909816989094169790971795909517949094161793909317808355610180850151919391929160ff60d01b1990911690600160d01b9084908111156111e0576111e0614120565b02179055506101a082015160098201556101c0820151600a8201556101e0820151600b820155610200820151600c820155610220820151600d8201906112269082614a65565b5061024082015181600e015590505061124461010380546001019055565b60fe546040516353eaf57560e11b8152600481018f9052602481018e9052604481018390526001600160a01b039091169063a7d5eaea90606401600060405180830381600087803b15801561129857600080fd5b505af11580156112ac573d6000803e3d6000fd5b5050505060408701516001600160a01b0316156112dd5760408701516112dd906001600160a01b03168730856129eb565b6112f188602001518860200151838e612a4b565b9750505050505050505b949350505050565b61130b612b66565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b600061137061292a565b6000848152610102602090815260408083205480845260fc909252909120600881015492935090916001600160a01b03808516600160301b90920416146114035760405162461bcd60e51b815260206004820152602160248201527f5468652063616c6c6572206d757374206265207468652061726269747261746f6044820152603960f91b60648201526084016109ac565b60036008820154600160d01b900460ff16600481111561142557611425614120565b146114805760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652068617320616c7265616479206265656e207265736044820152641bdb1d995960da1b60648201526084016109ac565b84836001600160a01b03167f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e75622276866040516114bc91815260200190565b60405180910390a36114ce8285612bdf565b5050505050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361151d5760405162461bcd60e51b81526004016109ac90614b25565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611566600080516020614f7f833981519152546001600160a01b031690565b6001600160a01b03161461158c5760405162461bcd60e51b81526004016109ac90614b71565b61159581612e69565b604080516000808252602082019092526115b191839190612e71565b50565b6115bc612b66565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee6910161135b565b611615612939565b60ff5483906001600160a01b0316632fa117e58261163161292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561167b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169f9190614bbd565b6116bb5760405162461bcd60e51b81526004016109ac90614bdf565b6116c88360008685612fdc565b600083815260fc60205260408120600481018054919285926116eb908490614c24565b92505081905550828160050160008282546117069190614c37565b909155506114ce905084846132c7565b600081815260fc60205260409020600e810154600c8201546117389042614c24565b10156117865760405162461bcd60e51b815260206004820152601f60248201527f54696d656f75742074696d6520686173206e6f7420706173736564207965740060448201526064016109ac565b60016008820154600160d01b900460ff1660048111156117a8576117a8614120565b0361182b57600a8101541561181c57600a81018054600091829055600183015460405191926001600160a01b0390911691839181818185875af1925050503d8060008114611812576040519150601f19603f3d011682016040523d82523d6000602084013e611817565b606091505b505050505b611827826002612bdf565b5050565b60026008820154600160d01b900460ff16600481111561184d5761184d614120565b0361182757600b810154156118c157600b81018054600091829055600283015460405191926001600160a01b0390911691839181818185875af1925050503d80600081146118b7576040519150601f19603f3d011682016040523d82523d6000602084013e6118bc565b606091505b505050505b611827826001612bdf565b6118d4612b66565b6118dc61330c565b565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036119265760405162461bcd60e51b81526004016109ac90614b25565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661196f600080516020614f7f833981519152546001600160a01b031690565b6001600160a01b0316146119955760405162461bcd60e51b81526004016109ac90614b71565b61199e82612e69565b61182782826001612e71565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a4a5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016109ac565b50600080516020614f7f83398151915290565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611a9c5760405162461bcd60e51b81526004016109ac90614c4a565b60036008820154600160d01b900460ff166004811115611abe57611abe614120565b10611adb5760405162461bcd60e51b81526004016109ac90614c76565b60028101546001600160a01b0316611af161292a565b6001600160a01b031614611b475760405162461bcd60e51b815260206004820152601f60248201527f5468652063616c6c6572206d757374206265207468652072656365697665720060448201526064016109ac565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611b8490600d860190600401614d66565b602060405180830381865afa158015611ba1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc59190614662565b90503482600b016000828254611bdb9190614c37565b9091555050600b8201548114611c525760405162461bcd60e51b815260206004820152603660248201527f54686520726563656976657220666565206d75737420626520657175616c20746044820152751bc81d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60521b60648201526084016109ac565b42600c8301556040518390600080516020614f9f83398151915290611c7e906000906001903490614d89565b60405180910390a28082600a01541015611ce75760088201805460ff60d01b1916600160d01b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611cda90600090614db3565b60405180910390a2505050565b611cf18382613364565b505050565b611cfe612b66565b6118dc60006135b7565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611d475760405162461bcd60e51b81526004016109ac90614c4a565b60036008820154600160d01b900460ff166004811115611d6957611d69614120565b10611d865760405162461bcd60e51b81526004016109ac90614c76565b60018101546001600160a01b0316611d9c61292a565b6001600160a01b031614611df25760405162461bcd60e51b815260206004820152601d60248201527f5468652063616c6c6572206d757374206265207468652073656e64657200000060448201526064016109ac565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611e2f90600d860190600401614d66565b602060405180830381865afa158015611e4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e709190614662565b90503482600a016000828254611e869190614c37565b9091555050600a8201548114611efb5760405162461bcd60e51b815260206004820152603460248201527f5468652073656e64657220666565206d75737420626520657175616c20746f206044820152731d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60621b60648201526084016109ac565b42600c8301556040518390600080516020614f9f83398151915290611f269060009081903490614d89565b60405180910390a28082600b01541015611ce75760088201805460ff60d01b1916600160d11b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611cda90600190614db3565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611fc15760405162461bcd60e51b81526004016109ac90614c4a565b6008810154600982015460405163093225f160e31b8152600160301b9092046001600160a01b0316916349912f889134916120049190600d870190600401614dc6565b6000604051808303818588803b15801561201d57600080fd5b505af1158015612031573d6000803e3d6000fd5b50505050505050565b612042612b66565b6118dc613609565b60ff5483906001600160a01b0316632fa117e58261206661292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156120b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d49190614bbd565b6120f05760405162461bcd60e51b81526004016109ac90614bdf565b8151602e1461212f5760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b60448201526064016109ac565b600083815260fc602052604090206008810154600160301b90046001600160a01b031661216e5760405162461bcd60e51b81526004016109ac90614c4a565b60ff546040516331a9108f60e11b8152600481018790526000916001600160a01b031690636352211e90602401602060405180830381865afa1580156121b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121dc9190614ddf565b60018301549091506001600160a01b038083169116148061220c575060028201546001600160a01b038281169116145b612280576040805162461bcd60e51b81526020600482015260248101919091527f5468652063616c6c6572206d757374206265207468652073656e646572206f7260448201527f20746865207265636569766572206f722074686569722064656c65676174657360648201526084016109ac565b60046008830154600160d01b900460ff1660048111156122a2576122a2614120565b106123095760405162461bcd60e51b815260206004820152603160248201527f4d757374206e6f742073656e642065766964656e6365206966207468652064696044820152701cdc1d5d19481a5cc81c995cdbdb1d9959607a1b60648201526084016109ac565b806001600160a01b0316858360080160069054906101000a90046001600160a01b03166001600160a01b03167fdccf2f8b2cc26eafcd61905cba744cff4b81d14740725f6376390dc6298a6a3c876040516123649190614dfc565b60405180910390a485857fd998ce0f89c38b0f93256f0b843a404a3a3c5055b75265623f7cb9c369a1dd628660405161239d9190614dfc565b60405180910390a3505050505050565b6123b5612939565b60ff5483906001600160a01b0316632fa117e5826123d161292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561241b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243f9190614bbd565b61245b5760405162461bcd60e51b81526004016109ac90614bdf565b6124688360018685612fdc565b600083815260fc602052604081206004810180549192859261248b908490614c24565b909155506114ce90508484613647565b6124a3612939565b60006124ad61292a565b6001600160a01b03166124c86033546001600160a01b031690565b6001600160a01b0316036125075782156124f45760405162461bcd60e51b81526004016109ac906149dc565b50610101546001600160a01b03166125d4565b6101005460405162f577a560e81b8152600481018590526001600160a01b039091169063f577a5009060240160006040518083038186803b15801561254b57600080fd5b505afa15801561255f573d6000803e3d6000fd5b5050610100546040516331a9108f60e11b8152600481018790526001600160a01b039091169250636352211e9150602401602060405180830381865afa1580156125ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d19190614ddf565b90505b600083815260fd602090815260408083206001600160a01b0386168452909152902054806126375760405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b60448201526064016109ac565b600084815260fd602090815260408083206001600160a01b03871684529091528120556126658284836136ad565b60408051858152602081018390526001600160a01b038516917f2227733fc4c8a9034cb58087dcf6995128b9c0233b038b03366aaf30c92b92d6910160405180910390a250505050565b6126b7612b66565b61010180546001600160a01b0319166001600160a01b0392909216919091179055565b6126e2612b66565b610101805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f8339189e972f7fba792126e752aa8485af08710bce4a041c5bc3f9858acd71309060200161135b565b61273b612b66565b6001600160a01b0381166127a05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109ac565b6115b1816135b7565b600054610100900460ff16158080156127c95750600054600160ff909116105b806127e35750303b1580156127e3575060005460ff166001145b6128465760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016109ac565b6000805460ff191660011790558015612869576000805461ff0019166101001790555b612871613787565b6128796137b6565b60fe80546001600160a01b038088166001600160a01b03199283161790925560ff805487841690831617905561010080548684169083161790556101018054928516929091169190911790556128d461010380546001019055565b6128de60646126da565b80156114ce576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b60006129346137dd565b905090565b60665460ff16156118dc5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016109ac565b600061271061299261ffff841686614e0f565b6129a061ffff861687614e0f565b610101546129b990600160a01b900461ffff1688614e0f565b6129c39190614c37565b6129cd9190614c37565b6129d79190614e26565b6129e19085614c37565b90505b9392505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612a45908590613816565b50505050565b600060fc600084815260200190815260200160002090507f8b4f0e94aa0aee74c276abd2d92a5e2737a493b055e19d5b2d4c0ac573242a158386868460030160009054906101000a90046001600160a01b031685600401548660060154876007015461010160149054906101000a900461ffff168960080160029054906101000a900461ffff168a60080160049054906101000a900461ffff168b60080160069054906101000a90046001600160a01b03168c600d018d600e0154604051612b1f9d9c9b9a99989796959493929190614e48565b60405180910390a1827f61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d83604051612b579190614dfc565b60405180910390a25050505050565b612b6e61292a565b6001600160a01b0316612b896033546001600160a01b031690565b6001600160a01b0316146118dc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ac565b600082815260fc602052604090206002821115612c2f5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c69642072756c696e6760901b60448201526064016109ac565b60018101546002820154600483018054600a85018054600b87018054600095869055928590559390935560088601805460ff60d01b1916600160d21b1790556001600160a01b0394851694909316929091906000198701612cea576040516001600160a01b038616908390600081818185875af1925050503d8060008114612cd3576040519150601f19603f3d011682016040523d82523d6000602084013e612cd8565b606091505b505050612ce58884613647565b612e25565b6001198701612d4e576040516001600160a01b038516908290600081818185875af1925050503d8060008114612d3c576040519150601f19603f3d011682016040523d82523d6000602084013e612d41565b606091505b505050612ce588846132c7565b6000612d5b600284614e26565b90506000612d6a600286614e26565b9050612d768a82613647565b612d808a826132c7565b6040516001600160a01b038816908390600081818185875af1925050503d8060008114612dc9576040519150601f19603f3d011682016040523d82523d6000602084013e612dce565b606091505b50506040516001600160a01b03881691508390600081818185875af1925050503d8060008114612e1a576040519150601f19603f3d011682016040523d82523d6000602084013e612e1f565b606091505b50505050505b877f76b363d70472d47d20e4119f3625c05ed37ca51b1d9e1cd8b87d8c20530640f388604051612e5791815260200190565b60405180910390a25050505050505050565b6115b1612b66565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612ea457611cf1836138e8565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612efe575060408051601f3d908101601f19168201909252612efb91810190614662565b60015b612f615760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016109ac565b600080516020614f7f8339815191528114612fd05760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016109ac565b50611cf1838383613984565b600084815260fc6020526040812090846001811115612ffd57612ffd614120565b036130a35760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa15801561304b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306f9190614ddf565b60018201546001600160a01b0390811691161461309e5760405162461bcd60e51b81526004016109ac906149dc565b613158565b60018460018111156130b7576130b7614120565b036131585760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa158015613105573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131299190614ddf565b60028201546001600160a01b039081169116146131585760405162461bcd60e51b81526004016109ac906149dc565b610103548154106131a45760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064016109ac565b60006008820154600160d01b900460ff1660048111156131c6576131c6614120565b146132215760405162461bcd60e51b815260206004820152602560248201527f546865207472616e73616374696f6e2073686f756c646e2774206265206469736044820152641c1d5d195960da1b60648201526084016109ac565b818160040154101561326a5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b60448201526064016109ac565b6127108210158061328a57506127108210801561328a5750806004015482145b6114ce5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016109ac565b6132d182826139a9565b600082815260fc6020526040902060028101546003820154613300916001600160a01b039081169116846136ad565b611cf183600084613c57565b613314613d7d565b6066805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61334761292a565b6040516001600160a01b03909116815260200160405180910390a1565b600082815260fc60205260409081902060088101805460ff60d01b1916600360d01b1790819055915163c13517e160e01b81529091600160301b90046001600160a01b031690819063c13517e19085906133c890600290600d880190600401614ed6565b60206040518083038185885af11580156133e6573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061340b9190614662565b600983018181556000918252610102602090815260409283902087905590548251878152918201879052916001600160a01b038416917f74baab670a4015ab2f1b467c5252a96141a2573f2908e58a92081e80d3cfde3d910160405180910390a38282600a015411156135175760008383600a015461348a9190614c24565b600a840185905560018401546040519192506001600160a01b0316908290600081818185875af1925050503d80600081146134e1576040519150601f19603f3d011682016040523d82523d6000602084013e6134e6565b606091505b50505084600080516020614f9f833981519152600160003460405161350d93929190614d89565b60405180910390a2505b8282600b01541115612a455760008383600b01546135359190614c24565b600b840185905560028401546040519192506001600160a01b0316908290600081818185875af1925050503d806000811461358c576040519150601f19603f3d011682016040523d82523d6000602084013e613591565b606091505b50505084600080516020614f9f83398151915260018034604051612b5793929190614d89565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b613611612939565b6066805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861334761292a565b600082815260fc60205260408120600881015490919061367d90849061ffff62010000820481169164010000000090041661297f565b600183015460038401549192506136a1916001600160a01b039182169116836136ad565b612a4584600185613c57565b6001600160a01b038216600003613714576040516001600160a01b038416908290600081818185875af1925050503d8060008114613707576040519150601f19603f3d011682016040523d82523d6000602084013e61370c565b606091505b505050505050565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb906044016020604051808303816000875af1158015613763573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a459190614bbd565b600054610100900460ff166137ae5760405162461bcd60e51b81526004016109ac90614ef2565b6118dc613dc6565b600054610100900460ff166118dc5760405162461bcd60e51b81526004016109ac90614ef2565b6000601436108015906137ff57503360009081526065602052604090205460ff165b15613811575060131936013560601c90565b503390565b600061386b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613dfd9092919063ffffffff16565b805190915015611cf157808060200190518101906138899190614bbd565b611cf15760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109ac565b6001600160a01b0381163b6139555760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016109ac565b600080516020614f7f83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61398d83613e0c565b60008251118061399a5750805b15611cf157612a458383613e4c565b600082815260fc602052604080822060fe5460068201546007830154935163353bb87f60e21b81526004810191909152602481019390935290929182916001600160a01b03169063d4eee1fc90604401600060405180830381865afa158015613a16573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613a3e91908101906147ab565b60a0820151608082015160088701549395509193509160009061271090613a6a90899061ffff16614e0f565b613a749190614e26565b600887015490915060009061271090613a98908a9062010000900461ffff16614e0f565b613aa29190614e26565b600888015490915060009061271090613ac8908b90640100000000900461ffff16614e0f565b613ad29190614e26565b60038901546001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc6020526040812080549293508592909190613b22908490614c37565b9091555050600085815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054849290613b5d908490614c37565b9091555050600084815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054839290613b98908490614c37565b90915550506003880154600689015460408051888152602081019290925281018490526001600160a01b03909116907f17c48ab8e1617182f35ae77fd7da7f4e15dedf7018aa371a4481c20c790b65469060600160405180910390a26003880154600689015460408051878152602081019290925281018490526001600160a01b03909116907f3476ed3eea2cdac584273bc8830824c8ca42ca2a99e9f144a87a1cdbbf9dd15a9060600160405180910390a250505050505050505050565b600083815260fc6020526040908190208054600382015460068301546007840154945193947ff3afebb51c3c2b45151cf0572b3d287505cf6ecea01df5f222c1d8cf0159f22794613cb8949389936001600160a01b03909116928992614f3d565b60405180910390a18060040154600003612a455760fe5460068201546005830154604051635ab9ae0f60e11b8152600481019290925260248201526001600160a01b039091169063b5735c1e90604401600060405180830381600087803b158015613d2257600080fd5b505af1158015613d36573d6000803e3d6000fd5b505050507f6bef1b5e95b741d6e665eb9b5c2d3e1203c46a771451055a9d41e0b8ff4510b78160060154604051613d6f91815260200190565b60405180910390a150505050565b60665460ff166118dc5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016109ac565b600054610100900460ff16613ded5760405162461bcd60e51b81526004016109ac90614ef2565b6118dc613df861292a565b6135b7565b60606129e18484600085613f42565b613e15816138e8565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b613eb45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016109ac565b600080846001600160a01b031684604051613ecf9190614a03565b600060405180830381855af49150503d8060008114613f0a576040519150601f19603f3d011682016040523d82523d6000602084013e613f0f565b606091505b5091509150613f378282604051806060016040528060278152602001614fbf6027913961401d565b925050505b92915050565b606082471015613fa35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016109ac565b600080866001600160a01b03168587604051613fbf9190614a03565b60006040518083038185875af1925050503d8060008114613ffc576040519150601f19603f3d011682016040523d82523d6000602084013e614001565b606091505b509150915061401287838387614036565b979650505050505050565b6060831561402c5750816129e4565b6129e483836140ab565b606083156140a557825160000361409e576001600160a01b0385163b61409e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109ac565b50816112fb565b6112fb83835b8151156140bb5781518083602001fd5b8060405162461bcd60e51b81526004016109ac9190614dfc565b6001600160a01b03811681146115b157600080fd5b6000602082840312156140fc57600080fd5b81356129e4816140d5565b60006020828403121561411957600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b6005811061414657614146614120565b9052565b60005b8381101561416557818101518382015260200161414d565b50506000910152565b6000815180845261418681602086016020860161414a565b601f01601f19169290920160200192915050565b6020815281516020820152600060208301516141c160408401826001600160a01b03169052565b5060408301516001600160a01b03811660608401525060608301516001600160a01b038116608084015250608083015160a083015260a083015160c083015260c083015160e083015260e08301516101008181850152808501519150506101206142308185018361ffff169052565b84015190506101406142478482018361ffff169052565b840151905061016061425e8482018361ffff169052565b840151905061018061427a848201836001600160a01b03169052565b84015190506101a061428e84820183614136565b8401516101c0848101919091528401516101e0808501919091528401516102008085019190915284015161022080850191909152840151610260610240808601829052919250906142e361028086018461416e565b9501519301929092525090919050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff8111828210171561432c5761432c6142f3565b60405290565b60405160c0810167ffffffffffffffff8111828210171561432c5761432c6142f3565b604051610160810167ffffffffffffffff8111828210171561432c5761432c6142f3565b604051601f8201601f1916810167ffffffffffffffff811182821017156143a2576143a26142f3565b604052919050565b600067ffffffffffffffff8211156143c4576143c46142f3565b50601f01601f191660200190565b60006143e56143e0846143aa565b614379565b90508281528383830111156143f957600080fd5b828260208301376000602084830101529392505050565b600082601f83011261442157600080fd5b6129e4838335602085016143d2565b6000806000806080858703121561444657600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561446c57600080fd5b61447888838901614410565b9350606087013591508082111561448e57600080fd5b5061449b87828801614410565b91505092959194509250565b600080604083850312156144ba57600080fd5b50508035926020909101359150565b6000806000606084860312156144de57600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561450857600080fd5b8235614513816140d5565b9150602083013567ffffffffffffffff81111561452f57600080fd5b8301601f8101851361454057600080fd5b61454f858235602084016143d2565b9150509250929050565b60008060006060848603121561456e57600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561459357600080fd5b61459f86828701614410565b9150509250925092565b600080604083850312156145bc57600080fd5b8235915060208301356145ce816140d5565b809150509250929050565b61ffff811681146115b157600080fd5b6000602082840312156145fb57600080fd5b81356129e4816145d9565b6000806000806080858703121561461c57600080fd5b8435614627816140d5565b93506020850135614637816140d5565b92506040850135614647816140d5565b91506060850135614657816140d5565b939692955090935050565b60006020828403121561467457600080fd5b5051919050565b600181811c9082168061468f57607f821691505b6020821081036146af57634e487b7160e01b600052602260045260246000fd5b50919050565b600082601f8301126146c657600080fd5b81516146d46143e0826143aa565b8181528460208386010111156146e957600080fd5b6112fb82602083016020870161414a565b80516002811061470957600080fd5b919050565b8051614709816140d5565b600060e0828403121561472b57600080fd5b614733614309565b905061473e826146fa565b8152602082015160208201526147566040830161470e565b6040820152606082015160608201526080820151608082015260a082015167ffffffffffffffff81111561478957600080fd5b614795848285016146b5565b60a08301525060c082015160c082015292915050565b600080604083850312156147be57600080fd5b825167ffffffffffffffff808211156147d657600080fd5b9084019060c082870312156147ea57600080fd5b6147f2614332565b82516005811061480157600080fd5b80825250602083015160208201526040830151604082015260608301518281111561482b57600080fd5b614837888286016146b5565b6060830152506080830151608082015260a083015160a082015280945050602085015191508082111561486957600080fd5b5061454f85828601614719565b6000806040838503121561488957600080fd5b8251614894816140d5565b60208401519092506145ce816140d5565b8051614709816145d9565b6000602082840312156148c257600080fd5b815167ffffffffffffffff808211156148da57600080fd5b9083019061016082860312156148ef57600080fd5b6148f7614355565b8251815260208301518281111561490d57600080fd5b614919878286016146b5565b60208301525060408301518281111561493157600080fd5b61493d878286016146b5565b60408301525061494f606084016148a5565b6060820152614960608084016148a5565b608082015260a083015160a082015260c083015160c082015261498560e0840161470e565b60e0820152610100808401518381111561499e57600080fd5b6149aa888287016146b5565b8284015250506101209150818301518282015261014091506149cd82840161470e565b91810191909152949350505050565b6020808252600d908201526c1058d8d95cdcc819195b9a5959609a1b604082015260600190565b60008251614a1581846020870161414a565b9190910192915050565b601f821115611cf157600081815260208120601f850160051c81016020861015614a465750805b601f850160051c820191505b8181101561370c57828155600101614a52565b815167ffffffffffffffff811115614a7f57614a7f6142f3565b614a9381614a8d845461467b565b84614a1f565b602080601f831160018114614ac85760008415614ab05750858301515b600019600386901b1c1916600185901b17855561370c565b600085815260208120601f198616915b82811015614af757888601518255948401946001909101908401614ad8565b5085821015614b155787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215614bcf57600080fd5b815180151581146129e457600080fd5b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b81810381811115613f3c57613f3c614c0e565b80820180821115613f3c57613f3c614c0e565b602080825260129082015271105c989a5d1c985d1bdc881b9bdd081cd95d60721b604082015260600190565b6020808252604d908201527f446973707574652068617320616c7265616479206265656e206372656174656460408201527f206f72206265636175736520746865207472616e73616374696f6e206861732060608201526c1899595b88195e1958dd5d1959609a1b608082015260a00190565b60008154614cf68161467b565b808552602060018381168015614d135760018114614d2d57614d5b565b60ff1985168884015283151560051b880183019550614d5b565b866000528260002060005b85811015614d535781548a8201860152908301908401614d38565b890184019650505b505050505092915050565b6020815260006129e46020830184614ce9565b600281106115b1576115b1614120565b60608101614d9685614d79565b848252614da284614d79565b602082019390935260400152919050565b60208101614dc083614d79565b91905290565b8281526040602082015260006129e16040830184614ce9565b600060208284031215614df157600080fd5b81516129e4816140d5565b6020815260006129e4602083018461416e565b8082028115828204841417613f3c57613f3c614c0e565b600082614e4357634e487b7160e01b600052601260045260246000fd5b500490565b8d8152602081018d9052604081018c90526001600160a01b038b81166060830152608082018b905260a082018a905260c0820189905261ffff88811660e08401528781166101008401528616610120830152841661014082015260006101a080610160840152614eba81840186614ce9565b915050826101808301529e9d5050505050505050505050505050565b60ff831681526040602082015260006129e16040830184614ce9565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b86815260c08101614f4d87614d79565b60208201969096526001600160a01b039490941660408501526060840192909252608083015260a09091015291905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc73e533bc8a993eccbc1023beebad0020f6b6c3639f83062f00fc194b4d1172ba416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a7f8bc736209ed86b0a75451b8ebeb8112ce6d951fbc6a029e99724cff4fa1e364736f6c63430008110033", + "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b60805161552c62000120600039600081816116390152818161167901528181611a4201528181611a820152611b11015261552c6000f3fe6080604052600436106101e35760003560e01c80635c0cd1e2116101025780638da5cb5b11610095578063e308a09911610064578063e308a09914610579578063eb63612d14610599578063f2fde38b146105b9578063f8c8765e146105d957600080fd5b80638da5cb5b146104fb5780639dcc5daf14610519578063d299630f14610539578063ddd5e1b21461055957600080fd5b80637b44cdb5116100d15780637b44cdb5146104a05780637e69b7b0146104b35780638456cb59146104c65780638b69fa0a146104db57600080fd5b80635c0cd1e2146104405780635c975abb146104605780636e72b45214610478578063715018a61461048b57600080fd5b80633751d89c1161017a5780634f1ef286116101495780634f1ef2861461039957806352d1902d146103ac578063572b6c05146103c15780635a34257a1461040a57600080fd5b80633751d89c146103245780633a1121cd146103445780633ab4a6a4146103645780633f4ba83a1461038457600080fd5b806326d00668116101b657806326d00668146102945780632fbe3b03146102b6578063311a6c56146102e45780633659cfe61461030457600080fd5b806306d6e63f146101e85780630a1a47d6146102265780630fa683d31461025457806315734fe714610281575b600080fd5b3480156101f457600080fd5b5061010154610209906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561023257600080fd5b506102466102413660046145c6565b6105f9565b60405190815260200161021d565b34801561026057600080fd5b5061027461026f3660046145e3565b610765565b60405161021d9190614676565b61024661028f366004614913565b610ae6565b3480156102a057600080fd5b506102b46102af3660046145c6565b61145d565b005b3480156102c257600080fd5b506102466102d13660046145e3565b6101026020526000908152604090205481565b3480156102f057600080fd5b506102b46102ff36600461498a565b6114c0565b34801561031057600080fd5b506102b461031f3660046145c6565b61162f565b34801561033057600080fd5b506102b461033f3660046145c6565b61170e565b34801561035057600080fd5b506102b461035f3660046149ac565b611767565b34801561037057600080fd5b506102b461037f3660046145e3565b611870565b34801561039057600080fd5b506102b4611a26565b6102b46103a73660046149d8565b611a38565b3480156103b857600080fd5b50610246611b04565b3480156103cd57600080fd5b506103fa6103dc3660046145c6565b6001600160a01b031660009081526065602052604090205460ff1690565b604051901515815260200161021d565b34801561041657600080fd5b506101015461042d90600160a01b900461ffff1681565b60405161ffff909116815260200161021d565b34801561044c57600080fd5b5061024661045b3660046145c6565b611bb7565b34801561046c57600080fd5b5060665460ff166103fa565b6102b46104863660046145e3565b611c6a565b34801561049757600080fd5b506102b4611f03565b6102b46104ae3660046145e3565b611f15565b6102b46104c13660046145e3565b61218f565b3480156104d257600080fd5b506102b4612247565b3480156104e757600080fd5b506102b46104f6366004614a3c565b612257565b34801561050757600080fd5b506033546001600160a01b0316610209565b34801561052557600080fd5b506102b46105343660046149ac565b6125ba565b34801561054557600080fd5b506102b4610554366004614a8c565b6126a8565b34801561056557600080fd5b506102b4610574366004614a8c565b61285a565b34801561058557600080fd5b506102b46105943660046145c6565b612a65565b3480156105a557600080fd5b506102b46105b4366004614acc565b612a90565b3480156105c557600080fd5b506102b46105d43660046145c6565b612ae9565b3480156105e557600080fd5b506102b46105f4366004614ae9565b612b5f565b600080610604612ce0565b9050806001600160a01b03166106226033546001600160a01b031690565b6001600160a01b03160361066c5750506001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc602052604090205490565b61010054604051631847c06b60e01b81526001600160a01b0383811660048301526000921690631847c06b90602401602060405180830381865afa1580156106b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106dc9190614b45565b6101005460405162f577a560e81b8152600481018390529192506001600160a01b03169063f577a5009060240160006040518083038186803b15801561072157600080fd5b505afa158015610735573d6000803e3d6000fd5b50505060009182525060fd602090815260408083206001600160a01b039096168352949052929092205492915050565b610814604080516102c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290529061018082019081526020016000815260200160008152602001600081526020016000815260200160608152602001600081526020016000815260200160008152602001600081525090565b600082815260fc6020908152604080832081516102c0810183528154815260018201546001600160a01b039081169482019490945260028201548416928101929092526003810154831660608301526004808201546080840152600582015460a0840152600682015460c0840152600782015460e0840152600882015461ffff8082166101008601526201000082048116610120860152640100000000820416610140850152600160301b810490941661016084015291929091610180840191600160d01b900460ff16908111156108ee576108ee6145fc565b60048111156108ff576108ff6145fc565b815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201805461093b90614b5e565b80601f016020809104026020016040519081016040528092919081815260200182805461096790614b5e565b80156109b45780601f10610989576101008083540402835291602001916109b4565b820191906000526020600020905b81548152906001019060200180831161099757829003601f168201915b50505050508152602001600e8201548152602001600f82015481526020016010820154815260200160118201548152505090506109f16101035490565b815110610a3e5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064015b60405180910390fd5b6000610a48612ce0565b905081602001516001600160a01b0316816001600160a01b03161480610a83575081604001516001600160a01b0316816001600160a01b0316145b610adf5760405162461bcd60e51b815260206004820152602760248201527f596f7520617265206e6f742072656c6174656420746f2074686973207472616e60448201526639b0b1ba34b7b760c91b6064820152608401610a35565b5092915050565b6000610af0612cef565b60fe5460405163353bb87f60e21b8152600481018790526024810186905260009182916001600160a01b039091169063d4eee1fc90604401600060405180830381865afa158015610b45573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b6d9190810190614ca8565b60ff54602083810151908301516040516303ef723760e61b81526004810192909252602482015292945090925060009182916001600160a01b03169063fbdc8dc0906044016040805180830381865afa158015610bce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf29190614d87565b6101005460a0870151604051630b7a459360e31b815260048101919091529294509092506000916001600160a01b0390911690635bd22c9890602401600060405180830381865afa158015610c4b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c739190810190614dc1565b9050600084608001518660a0015103610c8c5781610d09565b610100546080860151604051630b7a459360e31b81526001600160a01b0390921691635bd22c9891610cc49160040190815260200190565b600060405180830381865afa158015610ce1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d099190810190614dc1565b905060008560e00151600014610d23578660e00151610d26565b60005b90506000610d4287606001518560600151856080015185612d35565b60c08901519091506001600160a01b0316610da057803414610d9b5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b6044820152606401610a35565b610de3565b3415610de35760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b6044820152606401610a35565b856001600160a01b0316610df5612ce0565b6001600160a01b031614610e1b5760405162461bcd60e51b8152600401610a3590614eed565b8b876020015114610e665760405162461bcd60e51b8152602060048201526015602482015274125b98dbdc9c9958dd081c1c9bdc1bdcd85b081251605a1b6044820152606401610a35565b428760c001511015610ead5760405162461bcd60e51b815260206004820152601060248201526f141c9bdc1bdcd85b08195e1c1a5c995960821b6044820152606401610a35565b600088516004811115610ec257610ec26145fc565b14610f0f5760405162461bcd60e51b815260206004820152601760248201527f5365727669636520737461747573206e6f74206f70656e0000000000000000006044820152606401610a35565b600087516001811115610f2457610f246145fc565b14610f715760405162461bcd60e51b815260206004820152601b60248201527f50726f706f73616c20737461747573206e6f742070656e64696e6700000000006044820152606401610a35565b8a51602e14610fb05760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b6044820152606401610a35565b89604051602001610fc19190614f14565b604051602081830303815290604052805190602001208760a00151604051602001610fec9190614f14565b604051602081830303815290604052805190602001201461104f5760405162461bcd60e51b815260206004820152601c60248201527f50726f706f73616c206461746155726920686173206368616e676564000000006044820152606401610a35565b600061105b6101035490565b9050604051806102c00160405280828152602001886001600160a01b03168152602001876001600160a01b031681526020018a60c001516001600160a01b0316815260200189606001518152602001600081526020018f81526020018e815260200161010160149054906101000a900461ffff1661ffff168152602001866060015161ffff168152602001856080015161ffff1681526020018660e001516001600160a01b031681526020016000600481111561111a5761111a6145fc565b8152602001600081526020016000815260200160008152602001428152602001866101000151815260200186610120015181526020018960e0015181526020018a60e001518152602001896060015181525060fc60008381526020019081526020016000206000820151816000015560208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a0820151816005015560c0820151816006015560e082015181600701556101008201518160080160006101000a81548161ffff021916908361ffff1602179055506101208201518160080160026101000a81548161ffff021916908361ffff1602179055506101408201518160080160046101000a81548161ffff021916908361ffff1602179055506101608201518160080160066101000a8154816001600160a01b0302191690836001600160a01b0316021790555061018082015181600801601a6101000a81548160ff021916908360048111156112fd576112fd6145fc565b02179055506101a082015160098201556101c0820151600a8201556101e0820151600b820155610200820151600c820155610220820151600d8201906113439082614f76565b50610240820151600e820155610260820151600f82015561028082015160108201556102a09091015160119091015561138161010380546001019055565b60fe60009054906101000a90046001600160a01b03166001600160a01b031663a7d5eaea8f8f846040518463ffffffff1660e01b81526004016113d7939291909283526020830191909152604082015260600190565b600060405180830381600087803b1580156113f157600080fd5b505af1158015611405573d6000803e3d6000fd5b5050505060c08901516001600160a01b0316156114365760c0890151611436906001600160a01b0316883085612dae565b61144a89602001518960200151838f612e0e565b985050505050505050505b949350505050565b611465612f29565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b60006114ca612ce0565b6000848152610102602090815260408083205480845260fc909252909120600881015492935090916001600160a01b03808516600160301b909204161461155d5760405162461bcd60e51b815260206004820152602160248201527f5468652063616c6c6572206d757374206265207468652061726269747261746f6044820152603960f91b6064820152608401610a35565b60036008820154600160d01b900460ff16600481111561157f5761157f6145fc565b146115da5760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652068617320616c7265616479206265656e207265736044820152641bdb1d995960da1b6064820152608401610a35565b84836001600160a01b03167f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e756222768660405161161691815260200190565b60405180910390a36116288285612fa2565b5050505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036116775760405162461bcd60e51b8152600401610a3590615036565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166116c0600080516020615490833981519152546001600160a01b031690565b6001600160a01b0316146116e65760405162461bcd60e51b8152600401610a3590615082565b6116ef8161322c565b6040805160008082526020820190925261170b91839190613234565b50565b611716612f29565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee691016114b5565b61176f612cef565b60ff5483906001600160a01b0316632fa117e58261178b612ce0565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156117d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f991906150ce565b6118155760405162461bcd60e51b8152600401610a35906150f0565b611822836000868561339f565b600083815260fc6020526040812060048101805491928592611845908490615135565b92505081905550828160050160008282546118609190615148565b909155506116289050848461368a565b600081815260fc60205260409020600e810154600c8201546118929042615135565b10156118e05760405162461bcd60e51b815260206004820152601f60248201527f54696d656f75742074696d6520686173206e6f742070617373656420796574006044820152606401610a35565b60016008820154600160d01b900460ff166004811115611902576119026145fc565b0361198557600a8101541561197657600a81018054600091829055600183015460405191926001600160a01b0390911691839181818185875af1925050503d806000811461196c576040519150601f19603f3d011682016040523d82523d6000602084013e611971565b606091505b505050505b611981826002612fa2565b5050565b60026008820154600160d01b900460ff1660048111156119a7576119a76145fc565b0361198157600b81015415611a1b57600b81018054600091829055600283015460405191926001600160a01b0390911691839181818185875af1925050503d8060008114611a11576040519150601f19603f3d011682016040523d82523d6000602084013e611a16565b606091505b505050505b611981826001612fa2565b611a2e612f29565b611a366136cf565b565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003611a805760405162461bcd60e51b8152600401610a3590615036565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611ac9600080516020615490833981519152546001600160a01b031690565b6001600160a01b031614611aef5760405162461bcd60e51b8152600401610a3590615082565b611af88261322c565b61198182826001613234565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611ba45760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610a35565b5060008051602061549083398151915290565b60ff5460009081906001600160a01b0316631847c06b611bd5612ce0565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611c19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c3d9190614b45565b6000908152610104602090815260408083206001600160a01b039096168352949052929092205492915050565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611ca95760405162461bcd60e51b8152600401610a359061515b565b60036008820154600160d01b900460ff166004811115611ccb57611ccb6145fc565b10611ce85760405162461bcd60e51b8152600401610a3590615187565b60028101546001600160a01b0316611cfe612ce0565b6001600160a01b031614611d545760405162461bcd60e51b815260206004820152601f60248201527f5468652063616c6c6572206d75737420626520746865207265636569766572006044820152606401610a35565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611d9190600d860190600401615277565b602060405180830381865afa158015611dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd29190614b45565b90503482600b016000828254611de89190615148565b9091555050600b8201548114611e5f5760405162461bcd60e51b815260206004820152603660248201527f54686520726563656976657220666565206d75737420626520657175616c20746044820152751bc81d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60521b6064820152608401610a35565b42600c83015560405183906000805160206154b083398151915290611e8b90600090600190349061529a565b60405180910390a28082600a01541015611ef45760088201805460ff60d01b1916600160d01b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611ee7906000906152c4565b60405180910390a2505050565b611efe8382613727565b505050565b611f0b612f29565b611a36600061397a565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611f545760405162461bcd60e51b8152600401610a359061515b565b60036008820154600160d01b900460ff166004811115611f7657611f766145fc565b10611f935760405162461bcd60e51b8152600401610a3590615187565b60018101546001600160a01b0316611fa9612ce0565b6001600160a01b031614611fff5760405162461bcd60e51b815260206004820152601d60248201527f5468652063616c6c6572206d757374206265207468652073656e6465720000006044820152606401610a35565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea99061203c90600d860190600401615277565b602060405180830381865afa158015612059573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207d9190614b45565b90503482600a0160008282546120939190615148565b9091555050600a82015481146121085760405162461bcd60e51b815260206004820152603460248201527f5468652073656e64657220666565206d75737420626520657175616c20746f206044820152731d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60621b6064820152608401610a35565b42600c83015560405183906000805160206154b083398151915290612133906000908190349061529a565b60405180910390a28082600b01541015611ef45760088201805460ff60d01b1916600160d11b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611ee7906001906152c4565b600081815260fc602052604090206008810154600160301b90046001600160a01b03166121ce5760405162461bcd60e51b8152600401610a359061515b565b6008810154600982015460405163093225f160e31b8152600160301b9092046001600160a01b0316916349912f889134916122119190600d8701906004016152d7565b6000604051808303818588803b15801561222a57600080fd5b505af115801561223e573d6000803e3d6000fd5b50505050505050565b61224f612f29565b611a366139cc565b60ff5483906001600160a01b0316632fa117e582612273612ce0565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156122bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e191906150ce565b6122fd5760405162461bcd60e51b8152600401610a35906150f0565b8151602e1461233c5760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b6044820152606401610a35565b600083815260fc602052604090206008810154600160301b90046001600160a01b031661237b5760405162461bcd60e51b8152600401610a359061515b565b60ff546040516331a9108f60e11b8152600481018790526000916001600160a01b031690636352211e90602401602060405180830381865afa1580156123c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e991906152f0565b60018301549091506001600160a01b0380831691161480612419575060028201546001600160a01b038281169116145b61248d576040805162461bcd60e51b81526020600482015260248101919091527f5468652063616c6c6572206d757374206265207468652073656e646572206f7260448201527f20746865207265636569766572206f722074686569722064656c6567617465736064820152608401610a35565b60046008830154600160d01b900460ff1660048111156124af576124af6145fc565b106125165760405162461bcd60e51b815260206004820152603160248201527f4d757374206e6f742073656e642065766964656e6365206966207468652064696044820152701cdc1d5d19481a5cc81c995cdbdb1d9959607a1b6064820152608401610a35565b806001600160a01b0316858360080160069054906101000a90046001600160a01b03166001600160a01b03167fdccf2f8b2cc26eafcd61905cba744cff4b81d14740725f6376390dc6298a6a3c87604051612571919061530d565b60405180910390a485857fd998ce0f89c38b0f93256f0b843a404a3a3c5055b75265623f7cb9c369a1dd62866040516125aa919061530d565b60405180910390a3505050505050565b6125c2612cef565b60ff5483906001600160a01b0316632fa117e5826125de612ce0565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015612628573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264c91906150ce565b6126685760405162461bcd60e51b8152600401610a35906150f0565b612675836001868561339f565b600083815260fc6020526040812060048101805491928592612698908490615135565b9091555061162890508484613a0a565b6126b0612cef565b60ff5460405162f577a560e81b8152600481018490526000916001600160a01b03169063f577a5009060240160006040518083038186803b1580156126f457600080fd5b505afa158015612708573d6000803e3d6000fd5b505060ff546040516331a9108f60e11b8152600481018790526001600160a01b039091169250636352211e9150602401602060405180830381865afa158015612755573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061277991906152f0565b6000848152610104602090815260408083206001600160a01b0387168452909152902054909150806127e05760405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b6044820152606401610a35565b6000848152610104602090815260408083206001600160a01b038716845290915281205561280f828483613aa7565b60408051858152602081018390526001600160a01b038516917ff7c8cc6f18f75645957886fe11026a08ce70f199ba95cbb33ddd4064aa85203991015b60405180910390a250505050565b612862612cef565b600061286c612ce0565b6001600160a01b03166128876033546001600160a01b031690565b6001600160a01b0316036128c65782156128b35760405162461bcd60e51b8152600401610a3590614eed565b50610101546001600160a01b0316612993565b6101005460405162f577a560e81b8152600481018590526001600160a01b039091169063f577a5009060240160006040518083038186803b15801561290a57600080fd5b505afa15801561291e573d6000803e3d6000fd5b5050610100546040516331a9108f60e11b8152600481018790526001600160a01b039091169250636352211e9150602401602060405180830381865afa15801561296c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299091906152f0565b90505b600083815260fd602090815260408083206001600160a01b0386168452909152902054806129f65760405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b6044820152606401610a35565b600084815260fd602090815260408083206001600160a01b0387168452909152812055612a24828483613aa7565b60408051858152602081018390526001600160a01b038516917f2227733fc4c8a9034cb58087dcf6995128b9c0233b038b03366aaf30c92b92d6910161284c565b612a6d612f29565b61010180546001600160a01b0319166001600160a01b0392909216919091179055565b612a98612f29565b610101805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f8339189e972f7fba792126e752aa8485af08710bce4a041c5bc3f9858acd7130906020016114b5565b612af1612f29565b6001600160a01b038116612b565760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a35565b61170b8161397a565b600054610100900460ff1615808015612b7f5750600054600160ff909116105b80612b995750303b158015612b99575060005460ff166001145b612bfc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610a35565b6000805460ff191660011790558015612c1f576000805461ff0019166101001790555b612c27613b81565b612c2f613bb0565b60fe80546001600160a01b038088166001600160a01b03199283161790925560ff80548784169083161790556101008054868416908316179055610101805492851692909116919091179055612c8a61010380546001019055565b612c946064612a90565b8015611628576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6000612cea613bd7565b905090565b60665460ff1615611a365760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610a35565b600080612d428387615148565b9050612710612d5561ffff861683615320565b612d6361ffff881684615320565b61010154612d7c90600160a01b900461ffff1685615320565b612d869190615148565b612d909190615148565b612d9a9190615337565b612da49082615148565b9695505050505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612e08908590613c10565b50505050565b600060fc600084815260200190815260200160002090507f8b4f0e94aa0aee74c276abd2d92a5e2737a493b055e19d5b2d4c0ac573242a158386868460030160009054906101000a90046001600160a01b031685600401548660060154876007015461010160149054906101000a900461ffff168960080160029054906101000a900461ffff168a60080160049054906101000a900461ffff168b60080160069054906101000a90046001600160a01b03168c600d018d600e0154604051612ee29d9c9b9a99989796959493929190615359565b60405180910390a1827f61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d83604051612f1a919061530d565b60405180910390a25050505050565b612f31612ce0565b6001600160a01b0316612f4c6033546001600160a01b031690565b6001600160a01b031614611a365760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a35565b600082815260fc602052604090206002821115612ff25760405162461bcd60e51b815260206004820152600e60248201526d496e76616c69642072756c696e6760901b6044820152606401610a35565b60018101546002820154600483018054600a85018054600b87018054600095869055928590559390935560088601805460ff60d01b1916600160d21b1790556001600160a01b03948516949093169290919060001987016130ad576040516001600160a01b038616908390600081818185875af1925050503d8060008114613096576040519150601f19603f3d011682016040523d82523d6000602084013e61309b565b606091505b5050506130a88884613a0a565b6131e8565b6001198701613111576040516001600160a01b038516908290600081818185875af1925050503d80600081146130ff576040519150601f19603f3d011682016040523d82523d6000602084013e613104565b606091505b5050506130a8888461368a565b600061311e600284615337565b9050600061312d600286615337565b90506131398a82613a0a565b6131438a8261368a565b6040516001600160a01b038816908390600081818185875af1925050503d806000811461318c576040519150601f19603f3d011682016040523d82523d6000602084013e613191565b606091505b50506040516001600160a01b03881691508390600081818185875af1925050503d80600081146131dd576040519150601f19603f3d011682016040523d82523d6000602084013e6131e2565b606091505b50505050505b877f76b363d70472d47d20e4119f3625c05ed37ca51b1d9e1cd8b87d8c20530640f38860405161321a91815260200190565b60405180910390a25050505050505050565b61170b612f29565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561326757611efe83613ce2565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156132c1575060408051601f3d908101601f191682019092526132be91810190614b45565b60015b6133245760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610a35565b60008051602061549083398151915281146133935760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610a35565b50611efe838383613d7e565b600084815260fc60205260408120908460018111156133c0576133c06145fc565b036134665760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa15801561340e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061343291906152f0565b60018201546001600160a01b039081169116146134615760405162461bcd60e51b8152600401610a3590614eed565b61351b565b600184600181111561347a5761347a6145fc565b0361351b5760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa1580156134c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134ec91906152f0565b60028201546001600160a01b0390811691161461351b5760405162461bcd60e51b8152600401610a3590614eed565b610103548154106135675760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b6044820152606401610a35565b60006008820154600160d01b900460ff166004811115613589576135896145fc565b146135e45760405162461bcd60e51b815260206004820152602560248201527f546865207472616e73616374696f6e2073686f756c646e2774206265206469736044820152641c1d5d195960da1b6064820152608401610a35565b818160040154101561362d5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b6044820152606401610a35565b6127108210158061364d57506127108210801561364d5750806004015482145b6116285760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b6044820152606401610a35565b6136948282613da3565b600082815260fc60205260409020600281015460038201546136c3916001600160a01b03908116911684613aa7565b611efe83600084614129565b6136d761424f565b6066805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61370a612ce0565b6040516001600160a01b03909116815260200160405180910390a1565b600082815260fc60205260409081902060088101805460ff60d01b1916600360d01b1790819055915163c13517e160e01b81529091600160301b90046001600160a01b031690819063c13517e190859061378b90600290600d8801906004016153e7565b60206040518083038185885af11580156137a9573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906137ce9190614b45565b600983018181556000918252610102602090815260409283902087905590548251878152918201879052916001600160a01b038416917f74baab670a4015ab2f1b467c5252a96141a2573f2908e58a92081e80d3cfde3d910160405180910390a38282600a015411156138da5760008383600a015461384d9190615135565b600a840185905560018401546040519192506001600160a01b0316908290600081818185875af1925050503d80600081146138a4576040519150601f19603f3d011682016040523d82523d6000602084013e6138a9565b606091505b505050846000805160206154b083398151915260016000346040516138d09392919061529a565b60405180910390a2505b8282600b01541115612e085760008383600b01546138f89190615135565b600b840185905560028401546040519192506001600160a01b0316908290600081818185875af1925050503d806000811461394f576040519150601f19603f3d011682016040523d82523d6000602084013e613954565b606091505b505050846000805160206154b083398151915260018034604051612f1a9392919061529a565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6139d4612cef565b6066805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861370a612ce0565b600082815260fc6020526040812060118101549091908103613a2d576000613a4b565b60118201546010830154613a419085615320565b613a4b9190615337565b6008830154909150600090613a7790859061ffff62010000820481169164010000000090041685612d35565b60018401546003850154919250613a9b916001600160a01b03918216911683613aa7565b61162885600186614129565b6001600160a01b038216600003613b0e576040516001600160a01b038416908290600081818185875af1925050503d8060008114613b01576040519150601f19603f3d011682016040523d82523d6000602084013e613b06565b606091505b505050505050565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb906044016020604051808303816000875af1158015613b5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e0891906150ce565b600054610100900460ff16613ba85760405162461bcd60e51b8152600401610a3590615403565b611a36614298565b600054610100900460ff16611a365760405162461bcd60e51b8152600401610a3590615403565b600060143610801590613bf957503360009081526065602052604090205460ff165b15613c0b575060131936013560601c90565b503390565b6000613c65826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166142cf9092919063ffffffff16565b805190915015611efe5780806020019051810190613c8391906150ce565b611efe5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610a35565b6001600160a01b0381163b613d4f5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610a35565b60008051602061549083398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b613d87836142e8565b600082511180613d945750805b15611efe57612e088383614328565b600082815260fc602052604080822060fe5460068201546007830154935163353bb87f60e21b81526004810191909152602481019390935290929182916001600160a01b03169063d4eee1fc90604401600060405180830381865afa158015613e10573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613e389190810190614ca8565b60a0820151608082015160088701549395509193509160009061271090613e6490899061ffff16615320565b613e6e9190615337565b600887015490915060009061271090613e92908a9062010000900461ffff16615320565b613e9c9190615337565b600888015490915060009061271090613ec2908b90640100000000900461ffff16615320565b613ecc9190615337565b60038901546001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc6020526040812080549293508592909190613f1c908490615148565b9091555050600085815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054849290613f57908490615148565b9091555050600084815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054839290613f92908490615148565b9091555050600f88015415801590613fad5750601088015415155b1561406f576000886011015489601001548b613fc99190615320565b613fd39190615337565b600f8a015460009081526101046020908152604080832060038e01546001600160a01b03168452909152812080549293508392909190614014908490615148565b90915550506003890154600f8a015460068b015460408051918252602082018590526001600160a01b03909316927f7be8d1d5def43ba21be043f0d166965a1c479d40c0fac41f9a9fe18f1a9a2863910160405180910390a3505b6003880154600689015460408051888152602081019290925281018490526001600160a01b03909116907f17c48ab8e1617182f35ae77fd7da7f4e15dedf7018aa371a4481c20c790b65469060600160405180910390a26003880154600689015460408051878152602081019290925281018490526001600160a01b03909116907f3476ed3eea2cdac584273bc8830824c8ca42ca2a99e9f144a87a1cdbbf9dd15a9060600160405180910390a250505050505050505050565b600083815260fc6020526040908190208054600382015460068301546007840154945193947ff3afebb51c3c2b45151cf0572b3d287505cf6ecea01df5f222c1d8cf0159f2279461418a949389936001600160a01b0390911692899261544e565b60405180910390a18060040154600003612e085760fe5460068201546005830154604051635ab9ae0f60e11b8152600481019290925260248201526001600160a01b039091169063b5735c1e90604401600060405180830381600087803b1580156141f457600080fd5b505af1158015614208573d6000803e3d6000fd5b505050507f6bef1b5e95b741d6e665eb9b5c2d3e1203c46a771451055a9d41e0b8ff4510b7816006015460405161424191815260200190565b60405180910390a150505050565b60665460ff16611a365760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610a35565b600054610100900460ff166142bf5760405162461bcd60e51b8152600401610a3590615403565b611a366142ca612ce0565b61397a565b60606142de848460008561441e565b90505b9392505050565b6142f181613ce2565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6143905760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610a35565b600080846001600160a01b0316846040516143ab9190614f14565b600060405180830381855af49150503d80600081146143e6576040519150601f19603f3d011682016040523d82523d6000602084013e6143eb565b606091505b509150915061441382826040518060600160405280602781526020016154d0602791396144f9565b925050505b92915050565b60608247101561447f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610a35565b600080866001600160a01b0316858760405161449b9190614f14565b60006040518083038185875af1925050503d80600081146144d8576040519150601f19603f3d011682016040523d82523d6000602084013e6144dd565b606091505b50915091506144ee87838387614512565b979650505050505050565b606083156145085750816142e1565b6142e18383614587565b6060831561458157825160000361457a576001600160a01b0385163b61457a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a35565b5081611455565b61145583835b8151156145975781518083602001fd5b8060405162461bcd60e51b8152600401610a35919061530d565b6001600160a01b038116811461170b57600080fd5b6000602082840312156145d857600080fd5b81356142e1816145b1565b6000602082840312156145f557600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b60058110614622576146226145fc565b9052565b60005b83811015614641578181015183820152602001614629565b50506000910152565b60008151808452614662816020860160208601614626565b601f01601f19169290920160200192915050565b60208152815160208201526000602083015161469d60408401826001600160a01b03169052565b5060408301516001600160a01b03811660608401525060608301516001600160a01b038116608084015250608083015160a083015260a083015160c083015260c083015160e083015260e083015161010081818501528085015191505061012061470c8185018361ffff169052565b84015190506101406147238482018361ffff169052565b840151905061016061473a8482018361ffff169052565b8401519050610180614756848201836001600160a01b03169052565b84015190506101a061476a84820183614612565b8401516101c0848101919091528401516101e08085019190915284015161020080850191909152840151610220808501919091528401516102c0610240808601829052919250906147bf6102e086018461464a565b9086015161026086810191909152860151610280808701919091528601516102a080870191909152909501519301929092525090919050565b634e487b7160e01b600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715614832576148326147f8565b60405290565b604051610160810167ffffffffffffffff81118282101715614832576148326147f8565b604051601f8201601f1916810167ffffffffffffffff81118282101715614885576148856147f8565b604052919050565b600067ffffffffffffffff8211156148a7576148a76147f8565b50601f01601f191660200190565b60006148c86148c38461488d565b61485c565b90508281528383830111156148dc57600080fd5b828260208301376000602084830101529392505050565b600082601f83011261490457600080fd5b6142e1838335602085016148b5565b6000806000806080858703121561492957600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561494f57600080fd5b61495b888389016148f3565b9350606087013591508082111561497157600080fd5b5061497e878288016148f3565b91505092959194509250565b6000806040838503121561499d57600080fd5b50508035926020909101359150565b6000806000606084860312156149c157600080fd5b505081359360208301359350604090920135919050565b600080604083850312156149eb57600080fd5b82356149f6816145b1565b9150602083013567ffffffffffffffff811115614a1257600080fd5b8301601f81018513614a2357600080fd5b614a32858235602084016148b5565b9150509250929050565b600080600060608486031215614a5157600080fd5b8335925060208401359150604084013567ffffffffffffffff811115614a7657600080fd5b614a82868287016148f3565b9150509250925092565b60008060408385031215614a9f57600080fd5b823591506020830135614ab1816145b1565b809150509250929050565b61ffff8116811461170b57600080fd5b600060208284031215614ade57600080fd5b81356142e181614abc565b60008060008060808587031215614aff57600080fd5b8435614b0a816145b1565b93506020850135614b1a816145b1565b92506040850135614b2a816145b1565b91506060850135614b3a816145b1565b939692955090935050565b600060208284031215614b5757600080fd5b5051919050565b600181811c90821680614b7257607f821691505b602082108103614b9257634e487b7160e01b600052602260045260246000fd5b50919050565b805160058110614ba757600080fd5b919050565b600082601f830112614bbd57600080fd5b8151614bcb6148c38261488d565b818152846020838601011115614be057600080fd5b611455826020830160208701614626565b8051614ba7816145b1565b805160028110614ba757600080fd5b60006101008284031215614c1e57600080fd5b614c2661480e565b9050614c3182614bfc565b815260208201516020820152614c4960408301614bf1565b6040820152606082015160608201526080820151608082015260a082015167ffffffffffffffff811115614c7c57600080fd5b614c8884828501614bac565b60a08301525060c082015160c082015260e082015160e082015292915050565b60008060408385031215614cbb57600080fd5b825167ffffffffffffffff80821115614cd357600080fd5b908401906101008287031215614ce857600080fd5b614cf061480e565b614cf983614b98565b81526020830151602082015260408301516040820152606083015182811115614d2157600080fd5b614d2d88828601614bac565b6060830152506080830151608082015260a083015160a0820152614d5360c08401614bf1565b60c082015260e083015160e0820152809450506020850151915080821115614d7a57600080fd5b50614a3285828601614c0b565b60008060408385031215614d9a57600080fd5b8251614da5816145b1565b6020840151909250614ab1816145b1565b8051614ba781614abc565b600060208284031215614dd357600080fd5b815167ffffffffffffffff80821115614deb57600080fd5b908301906101608286031215614e0057600080fd5b614e08614838565b82518152602083015182811115614e1e57600080fd5b614e2a87828601614bac565b602083015250604083015182811115614e4257600080fd5b614e4e87828601614bac565b604083015250614e6060608401614db6565b6060820152614e7160808401614db6565b608082015260a083015160a082015260c083015160c0820152614e9660e08401614bf1565b60e08201526101008084015183811115614eaf57600080fd5b614ebb88828701614bac565b828401525050610120915081830151828201526101409150614ede828401614bf1565b91810191909152949350505050565b6020808252600d908201526c1058d8d95cdcc819195b9a5959609a1b604082015260600190565b60008251614f26818460208701614626565b9190910192915050565b601f821115611efe57600081815260208120601f850160051c81016020861015614f575750805b601f850160051c820191505b81811015613b0657828155600101614f63565b815167ffffffffffffffff811115614f9057614f906147f8565b614fa481614f9e8454614b5e565b84614f30565b602080601f831160018114614fd95760008415614fc15750858301515b600019600386901b1c1916600185901b178555613b06565b600085815260208120601f198616915b8281101561500857888601518255948401946001909101908401614fe9565b50858210156150265787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b6000602082840312156150e057600080fd5b815180151581146142e157600080fd5b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b818103818111156144185761441861511f565b808201808211156144185761441861511f565b602080825260129082015271105c989a5d1c985d1bdc881b9bdd081cd95d60721b604082015260600190565b6020808252604d908201527f446973707574652068617320616c7265616479206265656e206372656174656460408201527f206f72206265636175736520746865207472616e73616374696f6e206861732060608201526c1899595b88195e1958dd5d1959609a1b608082015260a00190565b6000815461520781614b5e565b808552602060018381168015615224576001811461523e5761526c565b60ff1985168884015283151560051b88018301955061526c565b866000528260002060005b858110156152645781548a8201860152908301908401615249565b890184019650505b505050505092915050565b6020815260006142e160208301846151fa565b6002811061170b5761170b6145fc565b606081016152a78561528a565b8482526152b38461528a565b602082019390935260400152919050565b602081016152d18361528a565b91905290565b8281526040602082015260006142de60408301846151fa565b60006020828403121561530257600080fd5b81516142e1816145b1565b6020815260006142e1602083018461464a565b80820281158282048414176144185761441861511f565b60008261535457634e487b7160e01b600052601260045260246000fd5b500490565b8d8152602081018d9052604081018c90526001600160a01b038b81166060830152608082018b905260a082018a905260c0820189905261ffff88811660e08401528781166101008401528616610120830152841661014082015260006101a0806101608401526153cb818401866151fa565b915050826101808301529e9d5050505050505050505050505050565b60ff831681526040602082015260006142de60408301846151fa565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b86815260c0810161545e8761528a565b60208201969096526001600160a01b039490941660408501526060840192909252608083015260a09091015291905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc73e533bc8a993eccbc1023beebad0020f6b6c3639f83062f00fc194b4d1172ba416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220ebf0fdcd633b2aa3cc45cd6844284d1b24a3cd790fcd8ef9ad87dff0726b7fe764736f6c63430008110033", + "deployedBytecode": "0x6080604052600436106101e35760003560e01c80635c0cd1e2116101025780638da5cb5b11610095578063e308a09911610064578063e308a09914610579578063eb63612d14610599578063f2fde38b146105b9578063f8c8765e146105d957600080fd5b80638da5cb5b146104fb5780639dcc5daf14610519578063d299630f14610539578063ddd5e1b21461055957600080fd5b80637b44cdb5116100d15780637b44cdb5146104a05780637e69b7b0146104b35780638456cb59146104c65780638b69fa0a146104db57600080fd5b80635c0cd1e2146104405780635c975abb146104605780636e72b45214610478578063715018a61461048b57600080fd5b80633751d89c1161017a5780634f1ef286116101495780634f1ef2861461039957806352d1902d146103ac578063572b6c05146103c15780635a34257a1461040a57600080fd5b80633751d89c146103245780633a1121cd146103445780633ab4a6a4146103645780633f4ba83a1461038457600080fd5b806326d00668116101b657806326d00668146102945780632fbe3b03146102b6578063311a6c56146102e45780633659cfe61461030457600080fd5b806306d6e63f146101e85780630a1a47d6146102265780630fa683d31461025457806315734fe714610281575b600080fd5b3480156101f457600080fd5b5061010154610209906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561023257600080fd5b506102466102413660046145c6565b6105f9565b60405190815260200161021d565b34801561026057600080fd5b5061027461026f3660046145e3565b610765565b60405161021d9190614676565b61024661028f366004614913565b610ae6565b3480156102a057600080fd5b506102b46102af3660046145c6565b61145d565b005b3480156102c257600080fd5b506102466102d13660046145e3565b6101026020526000908152604090205481565b3480156102f057600080fd5b506102b46102ff36600461498a565b6114c0565b34801561031057600080fd5b506102b461031f3660046145c6565b61162f565b34801561033057600080fd5b506102b461033f3660046145c6565b61170e565b34801561035057600080fd5b506102b461035f3660046149ac565b611767565b34801561037057600080fd5b506102b461037f3660046145e3565b611870565b34801561039057600080fd5b506102b4611a26565b6102b46103a73660046149d8565b611a38565b3480156103b857600080fd5b50610246611b04565b3480156103cd57600080fd5b506103fa6103dc3660046145c6565b6001600160a01b031660009081526065602052604090205460ff1690565b604051901515815260200161021d565b34801561041657600080fd5b506101015461042d90600160a01b900461ffff1681565b60405161ffff909116815260200161021d565b34801561044c57600080fd5b5061024661045b3660046145c6565b611bb7565b34801561046c57600080fd5b5060665460ff166103fa565b6102b46104863660046145e3565b611c6a565b34801561049757600080fd5b506102b4611f03565b6102b46104ae3660046145e3565b611f15565b6102b46104c13660046145e3565b61218f565b3480156104d257600080fd5b506102b4612247565b3480156104e757600080fd5b506102b46104f6366004614a3c565b612257565b34801561050757600080fd5b506033546001600160a01b0316610209565b34801561052557600080fd5b506102b46105343660046149ac565b6125ba565b34801561054557600080fd5b506102b4610554366004614a8c565b6126a8565b34801561056557600080fd5b506102b4610574366004614a8c565b61285a565b34801561058557600080fd5b506102b46105943660046145c6565b612a65565b3480156105a557600080fd5b506102b46105b4366004614acc565b612a90565b3480156105c557600080fd5b506102b46105d43660046145c6565b612ae9565b3480156105e557600080fd5b506102b46105f4366004614ae9565b612b5f565b600080610604612ce0565b9050806001600160a01b03166106226033546001600160a01b031690565b6001600160a01b03160361066c5750506001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc602052604090205490565b61010054604051631847c06b60e01b81526001600160a01b0383811660048301526000921690631847c06b90602401602060405180830381865afa1580156106b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106dc9190614b45565b6101005460405162f577a560e81b8152600481018390529192506001600160a01b03169063f577a5009060240160006040518083038186803b15801561072157600080fd5b505afa158015610735573d6000803e3d6000fd5b50505060009182525060fd602090815260408083206001600160a01b039096168352949052929092205492915050565b610814604080516102c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290529061018082019081526020016000815260200160008152602001600081526020016000815260200160608152602001600081526020016000815260200160008152602001600081525090565b600082815260fc6020908152604080832081516102c0810183528154815260018201546001600160a01b039081169482019490945260028201548416928101929092526003810154831660608301526004808201546080840152600582015460a0840152600682015460c0840152600782015460e0840152600882015461ffff8082166101008601526201000082048116610120860152640100000000820416610140850152600160301b810490941661016084015291929091610180840191600160d01b900460ff16908111156108ee576108ee6145fc565b60048111156108ff576108ff6145fc565b815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201805461093b90614b5e565b80601f016020809104026020016040519081016040528092919081815260200182805461096790614b5e565b80156109b45780601f10610989576101008083540402835291602001916109b4565b820191906000526020600020905b81548152906001019060200180831161099757829003601f168201915b50505050508152602001600e8201548152602001600f82015481526020016010820154815260200160118201548152505090506109f16101035490565b815110610a3e5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064015b60405180910390fd5b6000610a48612ce0565b905081602001516001600160a01b0316816001600160a01b03161480610a83575081604001516001600160a01b0316816001600160a01b0316145b610adf5760405162461bcd60e51b815260206004820152602760248201527f596f7520617265206e6f742072656c6174656420746f2074686973207472616e60448201526639b0b1ba34b7b760c91b6064820152608401610a35565b5092915050565b6000610af0612cef565b60fe5460405163353bb87f60e21b8152600481018790526024810186905260009182916001600160a01b039091169063d4eee1fc90604401600060405180830381865afa158015610b45573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b6d9190810190614ca8565b60ff54602083810151908301516040516303ef723760e61b81526004810192909252602482015292945090925060009182916001600160a01b03169063fbdc8dc0906044016040805180830381865afa158015610bce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf29190614d87565b6101005460a0870151604051630b7a459360e31b815260048101919091529294509092506000916001600160a01b0390911690635bd22c9890602401600060405180830381865afa158015610c4b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c739190810190614dc1565b9050600084608001518660a0015103610c8c5781610d09565b610100546080860151604051630b7a459360e31b81526001600160a01b0390921691635bd22c9891610cc49160040190815260200190565b600060405180830381865afa158015610ce1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d099190810190614dc1565b905060008560e00151600014610d23578660e00151610d26565b60005b90506000610d4287606001518560600151856080015185612d35565b60c08901519091506001600160a01b0316610da057803414610d9b5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b6044820152606401610a35565b610de3565b3415610de35760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b6044820152606401610a35565b856001600160a01b0316610df5612ce0565b6001600160a01b031614610e1b5760405162461bcd60e51b8152600401610a3590614eed565b8b876020015114610e665760405162461bcd60e51b8152602060048201526015602482015274125b98dbdc9c9958dd081c1c9bdc1bdcd85b081251605a1b6044820152606401610a35565b428760c001511015610ead5760405162461bcd60e51b815260206004820152601060248201526f141c9bdc1bdcd85b08195e1c1a5c995960821b6044820152606401610a35565b600088516004811115610ec257610ec26145fc565b14610f0f5760405162461bcd60e51b815260206004820152601760248201527f5365727669636520737461747573206e6f74206f70656e0000000000000000006044820152606401610a35565b600087516001811115610f2457610f246145fc565b14610f715760405162461bcd60e51b815260206004820152601b60248201527f50726f706f73616c20737461747573206e6f742070656e64696e6700000000006044820152606401610a35565b8a51602e14610fb05760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b6044820152606401610a35565b89604051602001610fc19190614f14565b604051602081830303815290604052805190602001208760a00151604051602001610fec9190614f14565b604051602081830303815290604052805190602001201461104f5760405162461bcd60e51b815260206004820152601c60248201527f50726f706f73616c206461746155726920686173206368616e676564000000006044820152606401610a35565b600061105b6101035490565b9050604051806102c00160405280828152602001886001600160a01b03168152602001876001600160a01b031681526020018a60c001516001600160a01b0316815260200189606001518152602001600081526020018f81526020018e815260200161010160149054906101000a900461ffff1661ffff168152602001866060015161ffff168152602001856080015161ffff1681526020018660e001516001600160a01b031681526020016000600481111561111a5761111a6145fc565b8152602001600081526020016000815260200160008152602001428152602001866101000151815260200186610120015181526020018960e0015181526020018a60e001518152602001896060015181525060fc60008381526020019081526020016000206000820151816000015560208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a0820151816005015560c0820151816006015560e082015181600701556101008201518160080160006101000a81548161ffff021916908361ffff1602179055506101208201518160080160026101000a81548161ffff021916908361ffff1602179055506101408201518160080160046101000a81548161ffff021916908361ffff1602179055506101608201518160080160066101000a8154816001600160a01b0302191690836001600160a01b0316021790555061018082015181600801601a6101000a81548160ff021916908360048111156112fd576112fd6145fc565b02179055506101a082015160098201556101c0820151600a8201556101e0820151600b820155610200820151600c820155610220820151600d8201906113439082614f76565b50610240820151600e820155610260820151600f82015561028082015160108201556102a09091015160119091015561138161010380546001019055565b60fe60009054906101000a90046001600160a01b03166001600160a01b031663a7d5eaea8f8f846040518463ffffffff1660e01b81526004016113d7939291909283526020830191909152604082015260600190565b600060405180830381600087803b1580156113f157600080fd5b505af1158015611405573d6000803e3d6000fd5b5050505060c08901516001600160a01b0316156114365760c0890151611436906001600160a01b0316883085612dae565b61144a89602001518960200151838f612e0e565b985050505050505050505b949350505050565b611465612f29565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b60006114ca612ce0565b6000848152610102602090815260408083205480845260fc909252909120600881015492935090916001600160a01b03808516600160301b909204161461155d5760405162461bcd60e51b815260206004820152602160248201527f5468652063616c6c6572206d757374206265207468652061726269747261746f6044820152603960f91b6064820152608401610a35565b60036008820154600160d01b900460ff16600481111561157f5761157f6145fc565b146115da5760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652068617320616c7265616479206265656e207265736044820152641bdb1d995960da1b6064820152608401610a35565b84836001600160a01b03167f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e756222768660405161161691815260200190565b60405180910390a36116288285612fa2565b5050505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036116775760405162461bcd60e51b8152600401610a3590615036565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166116c0600080516020615490833981519152546001600160a01b031690565b6001600160a01b0316146116e65760405162461bcd60e51b8152600401610a3590615082565b6116ef8161322c565b6040805160008082526020820190925261170b91839190613234565b50565b611716612f29565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee691016114b5565b61176f612cef565b60ff5483906001600160a01b0316632fa117e58261178b612ce0565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156117d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f991906150ce565b6118155760405162461bcd60e51b8152600401610a35906150f0565b611822836000868561339f565b600083815260fc6020526040812060048101805491928592611845908490615135565b92505081905550828160050160008282546118609190615148565b909155506116289050848461368a565b600081815260fc60205260409020600e810154600c8201546118929042615135565b10156118e05760405162461bcd60e51b815260206004820152601f60248201527f54696d656f75742074696d6520686173206e6f742070617373656420796574006044820152606401610a35565b60016008820154600160d01b900460ff166004811115611902576119026145fc565b0361198557600a8101541561197657600a81018054600091829055600183015460405191926001600160a01b0390911691839181818185875af1925050503d806000811461196c576040519150601f19603f3d011682016040523d82523d6000602084013e611971565b606091505b505050505b611981826002612fa2565b5050565b60026008820154600160d01b900460ff1660048111156119a7576119a76145fc565b0361198157600b81015415611a1b57600b81018054600091829055600283015460405191926001600160a01b0390911691839181818185875af1925050503d8060008114611a11576040519150601f19603f3d011682016040523d82523d6000602084013e611a16565b606091505b505050505b611981826001612fa2565b611a2e612f29565b611a366136cf565b565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003611a805760405162461bcd60e51b8152600401610a3590615036565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611ac9600080516020615490833981519152546001600160a01b031690565b6001600160a01b031614611aef5760405162461bcd60e51b8152600401610a3590615082565b611af88261322c565b61198182826001613234565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611ba45760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610a35565b5060008051602061549083398151915290565b60ff5460009081906001600160a01b0316631847c06b611bd5612ce0565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611c19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c3d9190614b45565b6000908152610104602090815260408083206001600160a01b039096168352949052929092205492915050565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611ca95760405162461bcd60e51b8152600401610a359061515b565b60036008820154600160d01b900460ff166004811115611ccb57611ccb6145fc565b10611ce85760405162461bcd60e51b8152600401610a3590615187565b60028101546001600160a01b0316611cfe612ce0565b6001600160a01b031614611d545760405162461bcd60e51b815260206004820152601f60248201527f5468652063616c6c6572206d75737420626520746865207265636569766572006044820152606401610a35565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611d9190600d860190600401615277565b602060405180830381865afa158015611dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd29190614b45565b90503482600b016000828254611de89190615148565b9091555050600b8201548114611e5f5760405162461bcd60e51b815260206004820152603660248201527f54686520726563656976657220666565206d75737420626520657175616c20746044820152751bc81d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60521b6064820152608401610a35565b42600c83015560405183906000805160206154b083398151915290611e8b90600090600190349061529a565b60405180910390a28082600a01541015611ef45760088201805460ff60d01b1916600160d01b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611ee7906000906152c4565b60405180910390a2505050565b611efe8382613727565b505050565b611f0b612f29565b611a36600061397a565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611f545760405162461bcd60e51b8152600401610a359061515b565b60036008820154600160d01b900460ff166004811115611f7657611f766145fc565b10611f935760405162461bcd60e51b8152600401610a3590615187565b60018101546001600160a01b0316611fa9612ce0565b6001600160a01b031614611fff5760405162461bcd60e51b815260206004820152601d60248201527f5468652063616c6c6572206d757374206265207468652073656e6465720000006044820152606401610a35565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea99061203c90600d860190600401615277565b602060405180830381865afa158015612059573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207d9190614b45565b90503482600a0160008282546120939190615148565b9091555050600a82015481146121085760405162461bcd60e51b815260206004820152603460248201527f5468652073656e64657220666565206d75737420626520657175616c20746f206044820152731d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60621b6064820152608401610a35565b42600c83015560405183906000805160206154b083398151915290612133906000908190349061529a565b60405180910390a28082600b01541015611ef45760088201805460ff60d01b1916600160d11b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611ee7906001906152c4565b600081815260fc602052604090206008810154600160301b90046001600160a01b03166121ce5760405162461bcd60e51b8152600401610a359061515b565b6008810154600982015460405163093225f160e31b8152600160301b9092046001600160a01b0316916349912f889134916122119190600d8701906004016152d7565b6000604051808303818588803b15801561222a57600080fd5b505af115801561223e573d6000803e3d6000fd5b50505050505050565b61224f612f29565b611a366139cc565b60ff5483906001600160a01b0316632fa117e582612273612ce0565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156122bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e191906150ce565b6122fd5760405162461bcd60e51b8152600401610a35906150f0565b8151602e1461233c5760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b6044820152606401610a35565b600083815260fc602052604090206008810154600160301b90046001600160a01b031661237b5760405162461bcd60e51b8152600401610a359061515b565b60ff546040516331a9108f60e11b8152600481018790526000916001600160a01b031690636352211e90602401602060405180830381865afa1580156123c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e991906152f0565b60018301549091506001600160a01b0380831691161480612419575060028201546001600160a01b038281169116145b61248d576040805162461bcd60e51b81526020600482015260248101919091527f5468652063616c6c6572206d757374206265207468652073656e646572206f7260448201527f20746865207265636569766572206f722074686569722064656c6567617465736064820152608401610a35565b60046008830154600160d01b900460ff1660048111156124af576124af6145fc565b106125165760405162461bcd60e51b815260206004820152603160248201527f4d757374206e6f742073656e642065766964656e6365206966207468652064696044820152701cdc1d5d19481a5cc81c995cdbdb1d9959607a1b6064820152608401610a35565b806001600160a01b0316858360080160069054906101000a90046001600160a01b03166001600160a01b03167fdccf2f8b2cc26eafcd61905cba744cff4b81d14740725f6376390dc6298a6a3c87604051612571919061530d565b60405180910390a485857fd998ce0f89c38b0f93256f0b843a404a3a3c5055b75265623f7cb9c369a1dd62866040516125aa919061530d565b60405180910390a3505050505050565b6125c2612cef565b60ff5483906001600160a01b0316632fa117e5826125de612ce0565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015612628573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264c91906150ce565b6126685760405162461bcd60e51b8152600401610a35906150f0565b612675836001868561339f565b600083815260fc6020526040812060048101805491928592612698908490615135565b9091555061162890508484613a0a565b6126b0612cef565b60ff5460405162f577a560e81b8152600481018490526000916001600160a01b03169063f577a5009060240160006040518083038186803b1580156126f457600080fd5b505afa158015612708573d6000803e3d6000fd5b505060ff546040516331a9108f60e11b8152600481018790526001600160a01b039091169250636352211e9150602401602060405180830381865afa158015612755573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061277991906152f0565b6000848152610104602090815260408083206001600160a01b0387168452909152902054909150806127e05760405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b6044820152606401610a35565b6000848152610104602090815260408083206001600160a01b038716845290915281205561280f828483613aa7565b60408051858152602081018390526001600160a01b038516917ff7c8cc6f18f75645957886fe11026a08ce70f199ba95cbb33ddd4064aa85203991015b60405180910390a250505050565b612862612cef565b600061286c612ce0565b6001600160a01b03166128876033546001600160a01b031690565b6001600160a01b0316036128c65782156128b35760405162461bcd60e51b8152600401610a3590614eed565b50610101546001600160a01b0316612993565b6101005460405162f577a560e81b8152600481018590526001600160a01b039091169063f577a5009060240160006040518083038186803b15801561290a57600080fd5b505afa15801561291e573d6000803e3d6000fd5b5050610100546040516331a9108f60e11b8152600481018790526001600160a01b039091169250636352211e9150602401602060405180830381865afa15801561296c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299091906152f0565b90505b600083815260fd602090815260408083206001600160a01b0386168452909152902054806129f65760405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b6044820152606401610a35565b600084815260fd602090815260408083206001600160a01b0387168452909152812055612a24828483613aa7565b60408051858152602081018390526001600160a01b038516917f2227733fc4c8a9034cb58087dcf6995128b9c0233b038b03366aaf30c92b92d6910161284c565b612a6d612f29565b61010180546001600160a01b0319166001600160a01b0392909216919091179055565b612a98612f29565b610101805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f8339189e972f7fba792126e752aa8485af08710bce4a041c5bc3f9858acd7130906020016114b5565b612af1612f29565b6001600160a01b038116612b565760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a35565b61170b8161397a565b600054610100900460ff1615808015612b7f5750600054600160ff909116105b80612b995750303b158015612b99575060005460ff166001145b612bfc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610a35565b6000805460ff191660011790558015612c1f576000805461ff0019166101001790555b612c27613b81565b612c2f613bb0565b60fe80546001600160a01b038088166001600160a01b03199283161790925560ff80548784169083161790556101008054868416908316179055610101805492851692909116919091179055612c8a61010380546001019055565b612c946064612a90565b8015611628576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6000612cea613bd7565b905090565b60665460ff1615611a365760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610a35565b600080612d428387615148565b9050612710612d5561ffff861683615320565b612d6361ffff881684615320565b61010154612d7c90600160a01b900461ffff1685615320565b612d869190615148565b612d909190615148565b612d9a9190615337565b612da49082615148565b9695505050505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612e08908590613c10565b50505050565b600060fc600084815260200190815260200160002090507f8b4f0e94aa0aee74c276abd2d92a5e2737a493b055e19d5b2d4c0ac573242a158386868460030160009054906101000a90046001600160a01b031685600401548660060154876007015461010160149054906101000a900461ffff168960080160029054906101000a900461ffff168a60080160049054906101000a900461ffff168b60080160069054906101000a90046001600160a01b03168c600d018d600e0154604051612ee29d9c9b9a99989796959493929190615359565b60405180910390a1827f61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d83604051612f1a919061530d565b60405180910390a25050505050565b612f31612ce0565b6001600160a01b0316612f4c6033546001600160a01b031690565b6001600160a01b031614611a365760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a35565b600082815260fc602052604090206002821115612ff25760405162461bcd60e51b815260206004820152600e60248201526d496e76616c69642072756c696e6760901b6044820152606401610a35565b60018101546002820154600483018054600a85018054600b87018054600095869055928590559390935560088601805460ff60d01b1916600160d21b1790556001600160a01b03948516949093169290919060001987016130ad576040516001600160a01b038616908390600081818185875af1925050503d8060008114613096576040519150601f19603f3d011682016040523d82523d6000602084013e61309b565b606091505b5050506130a88884613a0a565b6131e8565b6001198701613111576040516001600160a01b038516908290600081818185875af1925050503d80600081146130ff576040519150601f19603f3d011682016040523d82523d6000602084013e613104565b606091505b5050506130a8888461368a565b600061311e600284615337565b9050600061312d600286615337565b90506131398a82613a0a565b6131438a8261368a565b6040516001600160a01b038816908390600081818185875af1925050503d806000811461318c576040519150601f19603f3d011682016040523d82523d6000602084013e613191565b606091505b50506040516001600160a01b03881691508390600081818185875af1925050503d80600081146131dd576040519150601f19603f3d011682016040523d82523d6000602084013e6131e2565b606091505b50505050505b877f76b363d70472d47d20e4119f3625c05ed37ca51b1d9e1cd8b87d8c20530640f38860405161321a91815260200190565b60405180910390a25050505050505050565b61170b612f29565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561326757611efe83613ce2565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156132c1575060408051601f3d908101601f191682019092526132be91810190614b45565b60015b6133245760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610a35565b60008051602061549083398151915281146133935760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610a35565b50611efe838383613d7e565b600084815260fc60205260408120908460018111156133c0576133c06145fc565b036134665760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa15801561340e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061343291906152f0565b60018201546001600160a01b039081169116146134615760405162461bcd60e51b8152600401610a3590614eed565b61351b565b600184600181111561347a5761347a6145fc565b0361351b5760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa1580156134c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134ec91906152f0565b60028201546001600160a01b0390811691161461351b5760405162461bcd60e51b8152600401610a3590614eed565b610103548154106135675760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b6044820152606401610a35565b60006008820154600160d01b900460ff166004811115613589576135896145fc565b146135e45760405162461bcd60e51b815260206004820152602560248201527f546865207472616e73616374696f6e2073686f756c646e2774206265206469736044820152641c1d5d195960da1b6064820152608401610a35565b818160040154101561362d5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b6044820152606401610a35565b6127108210158061364d57506127108210801561364d5750806004015482145b6116285760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b6044820152606401610a35565b6136948282613da3565b600082815260fc60205260409020600281015460038201546136c3916001600160a01b03908116911684613aa7565b611efe83600084614129565b6136d761424f565b6066805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61370a612ce0565b6040516001600160a01b03909116815260200160405180910390a1565b600082815260fc60205260409081902060088101805460ff60d01b1916600360d01b1790819055915163c13517e160e01b81529091600160301b90046001600160a01b031690819063c13517e190859061378b90600290600d8801906004016153e7565b60206040518083038185885af11580156137a9573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906137ce9190614b45565b600983018181556000918252610102602090815260409283902087905590548251878152918201879052916001600160a01b038416917f74baab670a4015ab2f1b467c5252a96141a2573f2908e58a92081e80d3cfde3d910160405180910390a38282600a015411156138da5760008383600a015461384d9190615135565b600a840185905560018401546040519192506001600160a01b0316908290600081818185875af1925050503d80600081146138a4576040519150601f19603f3d011682016040523d82523d6000602084013e6138a9565b606091505b505050846000805160206154b083398151915260016000346040516138d09392919061529a565b60405180910390a2505b8282600b01541115612e085760008383600b01546138f89190615135565b600b840185905560028401546040519192506001600160a01b0316908290600081818185875af1925050503d806000811461394f576040519150601f19603f3d011682016040523d82523d6000602084013e613954565b606091505b505050846000805160206154b083398151915260018034604051612f1a9392919061529a565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6139d4612cef565b6066805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861370a612ce0565b600082815260fc6020526040812060118101549091908103613a2d576000613a4b565b60118201546010830154613a419085615320565b613a4b9190615337565b6008830154909150600090613a7790859061ffff62010000820481169164010000000090041685612d35565b60018401546003850154919250613a9b916001600160a01b03918216911683613aa7565b61162885600186614129565b6001600160a01b038216600003613b0e576040516001600160a01b038416908290600081818185875af1925050503d8060008114613b01576040519150601f19603f3d011682016040523d82523d6000602084013e613b06565b606091505b505050505050565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb906044016020604051808303816000875af1158015613b5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e0891906150ce565b600054610100900460ff16613ba85760405162461bcd60e51b8152600401610a3590615403565b611a36614298565b600054610100900460ff16611a365760405162461bcd60e51b8152600401610a3590615403565b600060143610801590613bf957503360009081526065602052604090205460ff165b15613c0b575060131936013560601c90565b503390565b6000613c65826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166142cf9092919063ffffffff16565b805190915015611efe5780806020019051810190613c8391906150ce565b611efe5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610a35565b6001600160a01b0381163b613d4f5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610a35565b60008051602061549083398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b613d87836142e8565b600082511180613d945750805b15611efe57612e088383614328565b600082815260fc602052604080822060fe5460068201546007830154935163353bb87f60e21b81526004810191909152602481019390935290929182916001600160a01b03169063d4eee1fc90604401600060405180830381865afa158015613e10573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613e389190810190614ca8565b60a0820151608082015160088701549395509193509160009061271090613e6490899061ffff16615320565b613e6e9190615337565b600887015490915060009061271090613e92908a9062010000900461ffff16615320565b613e9c9190615337565b600888015490915060009061271090613ec2908b90640100000000900461ffff16615320565b613ecc9190615337565b60038901546001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc6020526040812080549293508592909190613f1c908490615148565b9091555050600085815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054849290613f57908490615148565b9091555050600084815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054839290613f92908490615148565b9091555050600f88015415801590613fad5750601088015415155b1561406f576000886011015489601001548b613fc99190615320565b613fd39190615337565b600f8a015460009081526101046020908152604080832060038e01546001600160a01b03168452909152812080549293508392909190614014908490615148565b90915550506003890154600f8a015460068b015460408051918252602082018590526001600160a01b03909316927f7be8d1d5def43ba21be043f0d166965a1c479d40c0fac41f9a9fe18f1a9a2863910160405180910390a3505b6003880154600689015460408051888152602081019290925281018490526001600160a01b03909116907f17c48ab8e1617182f35ae77fd7da7f4e15dedf7018aa371a4481c20c790b65469060600160405180910390a26003880154600689015460408051878152602081019290925281018490526001600160a01b03909116907f3476ed3eea2cdac584273bc8830824c8ca42ca2a99e9f144a87a1cdbbf9dd15a9060600160405180910390a250505050505050505050565b600083815260fc6020526040908190208054600382015460068301546007840154945193947ff3afebb51c3c2b45151cf0572b3d287505cf6ecea01df5f222c1d8cf0159f2279461418a949389936001600160a01b0390911692899261544e565b60405180910390a18060040154600003612e085760fe5460068201546005830154604051635ab9ae0f60e11b8152600481019290925260248201526001600160a01b039091169063b5735c1e90604401600060405180830381600087803b1580156141f457600080fd5b505af1158015614208573d6000803e3d6000fd5b505050507f6bef1b5e95b741d6e665eb9b5c2d3e1203c46a771451055a9d41e0b8ff4510b7816006015460405161424191815260200190565b60405180910390a150505050565b60665460ff16611a365760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610a35565b600054610100900460ff166142bf5760405162461bcd60e51b8152600401610a3590615403565b611a366142ca612ce0565b61397a565b60606142de848460008561441e565b90505b9392505050565b6142f181613ce2565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6143905760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610a35565b600080846001600160a01b0316846040516143ab9190614f14565b600060405180830381855af49150503d80600081146143e6576040519150601f19603f3d011682016040523d82523d6000602084013e6143eb565b606091505b509150915061441382826040518060600160405280602781526020016154d0602791396144f9565b925050505b92915050565b60608247101561447f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610a35565b600080866001600160a01b0316858760405161449b9190614f14565b60006040518083038185875af1925050503d80600081146144d8576040519150601f19603f3d011682016040523d82523d6000602084013e6144dd565b606091505b50915091506144ee87838387614512565b979650505050505050565b606083156145085750816142e1565b6142e18383614587565b6060831561458157825160000361457a576001600160a01b0385163b61457a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a35565b5081611455565b61145583835b8151156145975781518083602001fd5b8060405162461bcd60e51b8152600401610a35919061530d565b6001600160a01b038116811461170b57600080fd5b6000602082840312156145d857600080fd5b81356142e1816145b1565b6000602082840312156145f557600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b60058110614622576146226145fc565b9052565b60005b83811015614641578181015183820152602001614629565b50506000910152565b60008151808452614662816020860160208601614626565b601f01601f19169290920160200192915050565b60208152815160208201526000602083015161469d60408401826001600160a01b03169052565b5060408301516001600160a01b03811660608401525060608301516001600160a01b038116608084015250608083015160a083015260a083015160c083015260c083015160e083015260e083015161010081818501528085015191505061012061470c8185018361ffff169052565b84015190506101406147238482018361ffff169052565b840151905061016061473a8482018361ffff169052565b8401519050610180614756848201836001600160a01b03169052565b84015190506101a061476a84820183614612565b8401516101c0848101919091528401516101e08085019190915284015161020080850191909152840151610220808501919091528401516102c0610240808601829052919250906147bf6102e086018461464a565b9086015161026086810191909152860151610280808701919091528601516102a080870191909152909501519301929092525090919050565b634e487b7160e01b600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715614832576148326147f8565b60405290565b604051610160810167ffffffffffffffff81118282101715614832576148326147f8565b604051601f8201601f1916810167ffffffffffffffff81118282101715614885576148856147f8565b604052919050565b600067ffffffffffffffff8211156148a7576148a76147f8565b50601f01601f191660200190565b60006148c86148c38461488d565b61485c565b90508281528383830111156148dc57600080fd5b828260208301376000602084830101529392505050565b600082601f83011261490457600080fd5b6142e1838335602085016148b5565b6000806000806080858703121561492957600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561494f57600080fd5b61495b888389016148f3565b9350606087013591508082111561497157600080fd5b5061497e878288016148f3565b91505092959194509250565b6000806040838503121561499d57600080fd5b50508035926020909101359150565b6000806000606084860312156149c157600080fd5b505081359360208301359350604090920135919050565b600080604083850312156149eb57600080fd5b82356149f6816145b1565b9150602083013567ffffffffffffffff811115614a1257600080fd5b8301601f81018513614a2357600080fd5b614a32858235602084016148b5565b9150509250929050565b600080600060608486031215614a5157600080fd5b8335925060208401359150604084013567ffffffffffffffff811115614a7657600080fd5b614a82868287016148f3565b9150509250925092565b60008060408385031215614a9f57600080fd5b823591506020830135614ab1816145b1565b809150509250929050565b61ffff8116811461170b57600080fd5b600060208284031215614ade57600080fd5b81356142e181614abc565b60008060008060808587031215614aff57600080fd5b8435614b0a816145b1565b93506020850135614b1a816145b1565b92506040850135614b2a816145b1565b91506060850135614b3a816145b1565b939692955090935050565b600060208284031215614b5757600080fd5b5051919050565b600181811c90821680614b7257607f821691505b602082108103614b9257634e487b7160e01b600052602260045260246000fd5b50919050565b805160058110614ba757600080fd5b919050565b600082601f830112614bbd57600080fd5b8151614bcb6148c38261488d565b818152846020838601011115614be057600080fd5b611455826020830160208701614626565b8051614ba7816145b1565b805160028110614ba757600080fd5b60006101008284031215614c1e57600080fd5b614c2661480e565b9050614c3182614bfc565b815260208201516020820152614c4960408301614bf1565b6040820152606082015160608201526080820151608082015260a082015167ffffffffffffffff811115614c7c57600080fd5b614c8884828501614bac565b60a08301525060c082015160c082015260e082015160e082015292915050565b60008060408385031215614cbb57600080fd5b825167ffffffffffffffff80821115614cd357600080fd5b908401906101008287031215614ce857600080fd5b614cf061480e565b614cf983614b98565b81526020830151602082015260408301516040820152606083015182811115614d2157600080fd5b614d2d88828601614bac565b6060830152506080830151608082015260a083015160a0820152614d5360c08401614bf1565b60c082015260e083015160e0820152809450506020850151915080821115614d7a57600080fd5b50614a3285828601614c0b565b60008060408385031215614d9a57600080fd5b8251614da5816145b1565b6020840151909250614ab1816145b1565b8051614ba781614abc565b600060208284031215614dd357600080fd5b815167ffffffffffffffff80821115614deb57600080fd5b908301906101608286031215614e0057600080fd5b614e08614838565b82518152602083015182811115614e1e57600080fd5b614e2a87828601614bac565b602083015250604083015182811115614e4257600080fd5b614e4e87828601614bac565b604083015250614e6060608401614db6565b6060820152614e7160808401614db6565b608082015260a083015160a082015260c083015160c0820152614e9660e08401614bf1565b60e08201526101008084015183811115614eaf57600080fd5b614ebb88828701614bac565b828401525050610120915081830151828201526101409150614ede828401614bf1565b91810191909152949350505050565b6020808252600d908201526c1058d8d95cdcc819195b9a5959609a1b604082015260600190565b60008251614f26818460208701614626565b9190910192915050565b601f821115611efe57600081815260208120601f850160051c81016020861015614f575750805b601f850160051c820191505b81811015613b0657828155600101614f63565b815167ffffffffffffffff811115614f9057614f906147f8565b614fa481614f9e8454614b5e565b84614f30565b602080601f831160018114614fd95760008415614fc15750858301515b600019600386901b1c1916600185901b178555613b06565b600085815260208120601f198616915b8281101561500857888601518255948401946001909101908401614fe9565b50858210156150265787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b6000602082840312156150e057600080fd5b815180151581146142e157600080fd5b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b818103818111156144185761441861511f565b808201808211156144185761441861511f565b602080825260129082015271105c989a5d1c985d1bdc881b9bdd081cd95d60721b604082015260600190565b6020808252604d908201527f446973707574652068617320616c7265616479206265656e206372656174656460408201527f206f72206265636175736520746865207472616e73616374696f6e206861732060608201526c1899595b88195e1958dd5d1959609a1b608082015260a00190565b6000815461520781614b5e565b808552602060018381168015615224576001811461523e5761526c565b60ff1985168884015283151560051b88018301955061526c565b866000528260002060005b858110156152645781548a8201860152908301908401615249565b890184019650505b505050505092915050565b6020815260006142e160208301846151fa565b6002811061170b5761170b6145fc565b606081016152a78561528a565b8482526152b38461528a565b602082019390935260400152919050565b602081016152d18361528a565b91905290565b8281526040602082015260006142de60408301846151fa565b60006020828403121561530257600080fd5b81516142e1816145b1565b6020815260006142e1602083018461464a565b80820281158282048414176144185761441861511f565b60008261535457634e487b7160e01b600052601260045260246000fd5b500490565b8d8152602081018d9052604081018c90526001600160a01b038b81166060830152608082018b905260a082018a905260c0820189905261ffff88811660e08401528781166101008401528616610120830152841661014082015260006101a0806101608401526153cb818401866151fa565b915050826101808301529e9d5050505050505050505050505050565b60ff831681526040602082015260006142de60408301846151fa565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b86815260c0810161545e8761528a565b60208201969096526001600160a01b039490941660408501526060840192909252608083015260a09091015291905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc73e533bc8a993eccbc1023beebad0020f6b6c3639f83062f00fc194b4d1172ba416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220ebf0fdcd633b2aa3cc45cd6844284d1b24a3cd790fcd8ef9ad87dff0726b7fe764736f6c63430008110033", "linkReferences": {}, "deployedLinkReferences": {} } From e7b097c06448d74cf77b47adee4522a0737b58df Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Sat, 2 Dec 2023 13:04:03 +0000 Subject: [PATCH 32/40] Update Service ABI --- .../client/src/contracts/ABI/TalentLayerService.json | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/client/src/contracts/ABI/TalentLayerService.json b/packages/client/src/contracts/ABI/TalentLayerService.json index 3153a47..9fcc20d 100644 --- a/packages/client/src/contracts/ABI/TalentLayerService.json +++ b/packages/client/src/contracts/ABI/TalentLayerService.json @@ -1364,11 +1364,6 @@ "name": "_serviceId", "type": "uint256" }, - { - "internalType": "address", - "name": "_rateToken", - "type": "address" - }, { "internalType": "uint256", "name": "_referralAmount", @@ -1417,8 +1412,8 @@ "type": "function" } ], - "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6080516144ec62000120600039600081816112d301528181611313015281816115ca0152818161160a015261169901526144ec6000f3fe6080604052600436106102305760003560e01c80636ce76f301161012e578063b5735c1e116100ab578063d547741f1161006f578063d547741f1461072e578063ef0e239b1461074e578063f2fde38b1461077b578063f6c53d9b1461079b578063f9eaee0d146107b257600080fd5b8063b5735c1e1461064a578063c22c4f431461066a578063c2cfee271461069e578063ccaa7d2a146106d2578063d4eee1fc1461070057600080fd5b806391d14854116100f257806391d14854146105b5578063a217fddf146105d5578063a24bd889146105ea578063a7d5eaea146105fd578063aba210091461061d57600080fd5b80636ce76f30146104dc578063715018a61461051057806371da85f9146105255780637c5a72cd146105775780638da5cb5b1461059757600080fd5b80632afaf220116101bc5780633ca2ad6f116101805780633ca2ad6f1461043b578063485cc9551461045b5780634f1ef2861461047b57806352d1902d1461048e578063572b6c05146104a357600080fd5b80632afaf220146103a85780632f2ff15d146103bb57806336568abe146103db5780633659cfe6146103fb5780633751d89c1461041b57600080fd5b8063156b39aa11610203578063156b39aa146102e557806319de9d6c1461030a5780631db087ff1461032a578063248a9ca31461035857806326d006681461038857600080fd5b806301ffc9a714610235578063089b7c731461026a5780631499f9e61461028c578063154664ed146102c5575b600080fd5b34801561024157600080fd5b506102556102503660046136a2565b6107ec565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061028a6102853660046136cc565b610823565b005b34801561029857600080fd5b50610130546102ad906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b3480156102d157600080fd5b5061028a6102e0366004613730565b6109c6565b3480156102f157600080fd5b506102fc6101365481565b604051908152602001610261565b34801561031657600080fd5b5061028a6103253660046137b5565b610cde565b34801561033657600080fd5b506102fc610345366004613828565b6101336020526000908152604090205481565b34801561036457600080fd5b506102fc610373366004613828565b600090815260fc602052604090206001015490565b34801561039457600080fd5b5061028a6103a3366004613841565b610f83565b6102fc6103b636600461385e565b610fe6565b3480156103c757600080fd5b5061028a6103d63660046138fe565b611211565b3480156103e757600080fd5b5061028a6103f63660046138fe565b61123b565b34801561040757600080fd5b5061028a610416366004613841565b6112c9565b34801561042757600080fd5b5061028a610436366004613841565b6113a8565b34801561044757600080fd5b5061028a610456366004613828565b611401565b34801561046757600080fd5b5061028a61047636600461392e565b611449565b61028a610489366004613972565b6115c0565b34801561049a57600080fd5b506102fc61168c565b3480156104af57600080fd5b506102556104be366004613841565b6001600160a01b031660009081526065602052604090205460ff1690565b3480156104e857600080fd5b506102fc7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f81565b34801561051c57600080fd5b5061028a61173f565b34801561053157600080fd5b50610560610540366004613841565b610135602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610261565b34801561058357600080fd5b5061028a610592366004613a44565b611753565b3480156105a357600080fd5b506033546001600160a01b03166102ad565b3480156105c157600080fd5b506102556105d03660046138fe565b611828565b3480156105e157600080fd5b506102fc600081565b61028a6105f8366004613a85565b611853565b34801561060957600080fd5b5061028a610618366004613b32565b611b6d565b34801561062957600080fd5b5061063d6106383660046136cc565b611bef565b6040516102619190613c50565b34801561065657600080fd5b5061028a6106653660046136cc565b611d2c565b34801561067657600080fd5b5061068a610685366004613828565b611dd1565b604051610261989796959493929190613c73565b3480156106aa57600080fd5b506106be6106b93660046136cc565b611eae565b604051610261989796959493929190613cd1565b3480156106de57600080fd5b506102fc6106ed366004613828565b6101346020526000908152604090205481565b34801561070c57600080fd5b5061072061071b3660046136cc565b611f95565b604051610261929190613da2565b34801561073a57600080fd5b5061028a6107493660046138fe565b61220b565b34801561075a57600080fd5b5061076e610769366004613828565b612230565b6040516102619190613dc7565b34801561078757600080fd5b5061028a610796366004613841565b6123b0565b3480156107a757600080fd5b506102fc61012e5481565b3480156107be57600080fd5b506102556107cd366004613841565b6001600160a01b03166000908152610135602052604090205460ff1690565b60006001600160e01b03198216637965db0b60e01b148061081d57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61012f5482906001600160a01b0316632fa117e582610840612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561088a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ae9190613dda565b6108d35760405162461bcd60e51b81526004016108ca90613df7565b60405180910390fd5b600082815261013160205260409020600181015484146109255760405162461bcd60e51b815260206004820152600d60248201526c3737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff16600481111561093d5761093d613b5e565b146109825760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b805460ff191660031781556040518381527f853aa4be1ac86f37acfc91d42b57f1fe895205aa6f8f9b7caa77ca257049ab1a9060200160405180910390a150505050565b61012f5487906001600160a01b0316632fa117e5826109e3612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a519190613dda565b610a6d5760405162461bcd60e51b81526004016108ca90613df7565b60008781526101316020908152604080832061013283528184208c855290925282209091825460ff166004811115610aa757610aa7613b5e565b14610ae95760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b89816001015414610b2c5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b602e8614610b4c5760405162461bcd60e51b81526004016108ca90613e26565b6001815460ff166001811115610b6457610b64613b5e565b03610ba55760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481d985b1a59185d1959607a1b60448201526064016108ca565b60068201546001600160a01b031660009081526101356020526040902060010154881015610c065760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b8315610c695761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015610c5057600080fd5b505afa158015610c64573d6000803e3d6000fd5b505050505b6003810188905560058101610c7f878983613ecb565b5060068101859055600781018490556040517ffbfaa6f4e508bec40137ac265a7424e16a2d209355b2f4a35de5a80ba8fec1db90610cca908b908d908b908b908e908c908c90613fb5565b60405180910390a150505050505050505050565b61012f5486906001600160a01b0316632fa117e582610cfb612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610d45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d699190613dda565b610d855760405162461bcd60e51b81526004016108ca90613df7565b60008681526101316020526040902060018101548814610dd75760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff166004811115610def57610def613b5e565b14610e345760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b602e8314610e545760405162461bcd60e51b81526004016108ca90613e26565b6001600160a01b0386166000908152610135602052604090205460ff16610eb15760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108ca565b8060070154851015610f055760405162461bcd60e51b815260206004820152601c60248201527f43616e27742072656475636520726566657272616c20616d6f756e740000000060448201526064016108ca565b60038101610f14848683613ecb565b50600781018590556006810180546001600160a01b0319166001600160a01b0388161790556040517f79dba2b7507f91f38c9a67e52f174c234541b20eccc91ad6afe9d3753f6371f590610f71908990879087908b908b90613ff4565b60405180910390a15050505050505050565b610f8b612435565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b61012f5460009089906001600160a01b0316632fa117e582611006612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611050573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110749190613dda565b6110905760405162461bcd60e51b81526004016108ca90613df7565b61109f8a8a8a8a8a8a8a6124ae565b61012e805490819060006110b283614041565b9091555050600081815261013160205260409020805460ff19168155600181018c9055600381016110e48a8c83613ecb565b50600581018b90556006810180546001600160a01b0319166001600160a01b0388161790556007810185905560008c8152610133602052604090205415801561113a575060008c81526101346020526040902054155b1561119f5761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b15801561118657600080fd5b505af115801561119a573d6000803e3d6000fd5b505050505b60008c8152610133602052604081208054916111ba83614041565b91905055507fe7f6435fc92b0ccd6f56395ae67b06f2cdb9680c0179f87f5821431304ad3f3e828d8d8d8d8b8b6040516111fa979695949392919061405a565b60405180910390a1509a9950505050505050505050565b600082815260fc602052604090206001015461122c816126b7565b61123683836126c8565b505050565b611243612426565b6001600160a01b0316816001600160a01b0316146112bb5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108ca565b6112c5828261274f565b5050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036113115760405162461bcd60e51b81526004016108ca9061409f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661135a600080516020614470833981519152546001600160a01b031690565b6001600160a01b0316146113805760405162461bcd60e51b81526004016108ca906140eb565b611389816127d4565b604080516000808252602082019092526113a5918391906127dc565b50565b6113b0612435565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee69101610fdb565b600061140c816126b7565b6101368290556040518281527f577d7afcf67637a2f602cba220bbb292c1d715380dd011bfec748c3f641b2fd29060200160405180910390a15050565b600054610100900460ff16158080156114695750600054600160ff909116105b806114835750303b158015611483575060005460ff166001145b6114e65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108ca565b6000805460ff191660011790558015611509576000805461ff0019166101001790555b611511612947565b611519612976565b611521612976565b611533600061152e612426565b61299d565b61012f80546001600160a01b038086166001600160a01b031992831617909255610130805492851692909116919091179055600161012e55611575601e611401565b8015611236576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036116085760405162461bcd60e51b81526004016108ca9061409f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611651600080516020614470833981519152546001600160a01b031690565b6001600160a01b0316146116775760405162461bcd60e51b81526004016108ca906140eb565b611680826127d4565b6112c5828260016127dc565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461172c5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108ca565b5060008051602061447083398151915290565b611747612435565b61175160006129a7565b565b61175b612435565b6001600160a01b038316158015611770575081155b156117bd5760405162461bcd60e51b815260206004820152601d60248201527f4f776e65722063616e27742072656d6f7665204f78206164647265737300000060448201526064016108ca565b6001600160a01b03831660008181526101356020908152604091829020805460ff19168615159081178255600190910185905582519384529083015281018290527f42b585a1da1cff4b571e7a78aea1b4601b1d128de41a0feebd8a77aaf48b9d88906060016115b3565b600091825260fc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61012f548a906001600160a01b0316632fa117e582611870612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156118ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118de9190613dda565b6118fa5760405162461bcd60e51b81526004016108ca90613df7565b60008a81526101316020526040902061191a8c8c8c8c8c8c8b8b8b6129f9565b60408051610100810182526000815260208082018f905260068401546001600160a01b031682840152606082018d9052608082018c90528251601f8b01829004820281018201909352898352909160a08301918b908b9081908401838280828437600081840152601f19601f8201169050808301925050505050505081526020018781526020018481525061013260008d815260200190815260200160002060008e815260200190815260200160002060008201518160000160006101000a81548160ff021916908360018111156119f4576119f4613b5e565b02179055506020820151600182015560408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a08201516005820190611a519082614137565b5060c0820151600682015560e09091015160079091015560008c81526101336020526040902054158015611a92575060008c81526101346020526040902054155b15611af75761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015611ade57600080fd5b505af1158015611af2573d6000803e3d6000fd5b505050505b60008c815261013460205260408120805491611b1283614041565b91905055507fabd26455c3256ad90125661f4c1a4c16fecf585ccade21e749c56d8fd44bb1dd8b8d8a8a60008f8f8d8b604051611b57999897969594939291906141f7565b60405180910390a1505050505050505050505050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611b97816126b7565b60008481526101316020908152604080832061013283528184208785529092529091208154600160ff1991821681178455808301546002850155600484018690558254909183911682805b0217905550505050505050565b611bf7613604565b60008381526101326020908152604080832085845290915290819020815161010081019092528054829060ff166001811115611c3557611c35613b5e565b6001811115611c4657611c46613b5e565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611c8e90613e4b565b80601f0160208091040260200160405190810160405280929190818152602001828054611cba90613e4b565b8015611d075780601f10611cdc57610100808354040283529160200191611d07565b820191906000526020600020905b815481529060010190602001808311611cea57829003601f168201915b5050505050815260200160068201548152602001600782015481525050905092915050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611d56816126b7565b6000838152610131602090815260408083206101328352818420600282015485529092528220600381015491929091611d9086606461424e565b611d9a9190614265565b9050610136548110611db657825460ff19166002178355611dc9565b8254600490849060ff1916600183611be2565b505050505050565b61013160205260009081526040902080546001820154600283015460038401805460ff909416949293919291611e0690613e4b565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3290613e4b565b8015611e7f5780601f10611e5457610100808354040283529160200191611e7f565b820191906000526020600020905b815481529060010190602001808311611e6257829003601f168201915b505050600484015460058501546006860154600790960154949591949093506001600160a01b03909116915088565b61013260209081526000928352604080842090915290825290208054600182015460028301546003840154600485015460058601805460ff9096169694956001600160a01b03909416949293919291611f0690613e4b565b80601f0160208091040260200160405190810160405280929190818152602001828054611f3290613e4b565b8015611f7f5780601f10611f5457610100808354040283529160200191611f7f565b820191906000526020600020905b815481529060010190602001808311611f6257829003601f168201915b5050505050908060060154908060070154905088565b611f9d613653565b611fa5613604565b60008481526101316020526040808220815161010081019092528054829060ff166004811115611fd757611fd7613b5e565b6004811115611fe857611fe8613b5e565b8152602001600182015481526020016002820154815260200160038201805461201090613e4b565b80601f016020809104026020016040519081016040528092919081815260200182805461203c90613e4b565b80156120895780601f1061205e57610100808354040283529160200191612089565b820191906000526020600020905b81548152906001019060200180831161206c57829003601f168201915b50505091835250506004820154602080830191909152600583015460408084019190915260068401546001600160a01b03166060840152600790930154608090920191909152600088815261013282528281208882529091528181208251610100810190935280549394509092829060ff16600181111561210c5761210c613b5e565b600181111561211d5761211d613b5e565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a09092019161216590613e4b565b80601f016020809104026020016040519081016040528092919081815260200182805461219190613e4b565b80156121de5780601f106121b3576101008083540402835291602001916121de565b820191906000526020600020905b8154815290600101906020018083116121c157829003601f168201915b505050918352505060068201546020820152600790910154604090910152919350909150505b9250929050565b600082815260fc6020526040902060010154612226816126b7565b611236838361274f565b612238613653565b61012e54821061228a5760405162461bcd60e51b815260206004820152601a60248201527f54686973207365727669636520646f65736e277420657869737400000000000060448201526064016108ca565b6000828152610131602052604090819020815161010081019092528054829060ff1660048111156122bd576122bd613b5e565b60048111156122ce576122ce613b5e565b815260200160018201548152602001600282015481526020016003820180546122f690613e4b565b80601f016020809104026020016040519081016040528092919081815260200182805461232290613e4b565b801561236f5780601f106123445761010080835404028352916020019161236f565b820191906000526020600020905b81548152906001019060200180831161235257829003601f168201915b5050509183525050600482015460208201526005820154604082015260068201546001600160a01b0316606082015260079091015460809091015292915050565b6123b8612435565b6001600160a01b03811661241d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108ca565b6113a5816129a7565b6000612430612de0565b905090565b61243d612426565b6001600160a01b03166124586033546001600160a01b031690565b6001600160a01b0316146117515760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108ca565b61013054604051638a98636360e01b8152600481018890526000916001600160a01b031690638a98636390602401602060405180830381865afa1580156124f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061251d9190614287565b90508034146125635760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b602e85146125835760405162461bcd60e51b81526004016108ca90613e26565b6001600160a01b0382166000908152610135602052604090205460ff166125e05760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108ca565b61013054604051631fff7f2760e11b8152600481018990526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa15801561262b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264f91906142a0565b90506001600160a01b038116156126ac57600089815261013360209081526040808320549051612686928d92918c918c91016142bd565b6040516020818303038152906040528051906020012090506126aa86868385612e19565b505b505050505050505050565b6113a5816126c3612426565b612f0d565b6126d28282611828565b6112c557600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561270b612426565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6127598282611828565b156112c557600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff19169055612790612426565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6113a5612435565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561280f5761123683612f66565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612869575060408051601f3d908101601f1916820190925261286691810190614287565b60015b6128cc5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108ca565b600080516020614470833981519152811461293b5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108ca565b50611236838383613002565b600054610100900460ff1661296e5760405162461bcd60e51b81526004016108ca906142fe565b61175161302d565b600054610100900460ff166117515760405162461bcd60e51b81526004016108ca906142fe565b6112c582826126c8565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61013054604051634a7ab1d560e01b8152600481018890526000916001600160a01b031690634a7ab1d590602401602060405180830381865afa158015612a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a689190614287565b9050803414612aae5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b60008981526101316020908152604080832060068101546001600160a01b03168452610135909252909120600101546007820154612aec908b614349565b1015612b2b5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b6000815460ff166004811115612b4357612b43613b5e565b14612b855760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b8060010154600003612bcd5760405162461bcd60e51b815260206004820152601160248201527014d95c9d9a58d9481b9bdd08195e1a5cdd607a1b60448201526064016108ca565b60008a8152610132602090815260408083208e84529091529020600101548b9003612c335760405162461bcd60e51b81526020600482015260166024820152751c1c9bdc1bdcd85b08185b1c9958591e48195e1a5cdd60521b60448201526064016108ca565b8a816001015403612c905760405162461bcd60e51b815260206004820152602160248201527f63616e27742063726561746520666f7220796f7572206f776e207365727669636044820152606560f81b60648201526084016108ca565b602e8614612cb05760405162461bcd60e51b81526004016108ca90613e26565b61013054604051631fff7f2760e11b8152600481018a90526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612cfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d1f91906142a0565b90506001600160a01b03811615612d6f5760008c8c8a8a604051602001612d49949392919061435c565b604051602081830303815290604052805190602001209050612d6d87878385612e19565b505b8315612dd25761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015612db957600080fd5b505afa158015612dcd573d6000803e3d6000fd5b505050505b505050505050505050505050565b600060143610801590612e0257503360009081526065602052604090205460ff165b15612e14575060131936013560601c90565b503390565b6000612e72836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000612eb68287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061306492505050565b9050806001600160a01b0316836001600160a01b031614611dc95760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064016108ca565b612f178282611828565b6112c557612f2481613088565b612f2f83602061309a565b604051602001612f4092919061439e565b60408051601f198184030181529082905262461bcd60e51b82526108ca91600401614413565b6001600160a01b0381163b612fd35760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108ca565b60008051602061447083398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61300b8361323d565b6000825111806130185750805b1561123657613027838361327d565b50505050565b600054610100900460ff166130545760405162461bcd60e51b81526004016108ca906142fe565b61175161305f612426565b6129a7565b60008060006130738585613371565b91509150613080816133b3565b509392505050565b606061081d6001600160a01b03831660145b606060006130a983600261424e565b6130b4906002614349565b67ffffffffffffffff8111156130cc576130cc61395c565b6040519080825280601f01601f1916602001820160405280156130f6576020820181803683370190505b509050600360fc1b8160008151811061311157613111614426565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061314057613140614426565b60200101906001600160f81b031916908160001a905350600061316484600261424e565b61316f906001614349565b90505b60018111156131e7576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106131a3576131a3614426565b1a60f81b8282815181106131b9576131b9614426565b60200101906001600160f81b031916908160001a90535060049490941c936131e08161443c565b9050613172565b5083156132365760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108ca565b9392505050565b61324681612f66565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6132e55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108ca565b600080846001600160a01b0316846040516133009190614453565b600060405180830381855af49150503d806000811461333b576040519150601f19603f3d011682016040523d82523d6000602084013e613340565b606091505b50915091506133688282604051806060016040528060278152602001614490602791396134fd565b95945050505050565b60008082516041036133a75760208301516040840151606085015160001a61339b87828585613516565b94509450505050612204565b50600090506002612204565b60008160048111156133c7576133c7613b5e565b036133cf5750565b60018160048111156133e3576133e3613b5e565b036134305760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108ca565b600281600481111561344457613444613b5e565b036134915760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108ca565b60038160048111156134a5576134a5613b5e565b036113a55760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108ca565b6060831561350c575081613236565b61323683836135da565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561354d57506000905060036135d1565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156135a1573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166135ca576000600192509250506135d1565b9150600090505b94509492505050565b8151156135ea5781518083602001fd5b8060405162461bcd60e51b81526004016108ca9190614413565b60408051610100810190915280600081526020016000815260200160006001600160a01b0316815260200160008152602001600081526020016060815260200160008152602001600081525090565b6040805161010081019091528060008152602001600081526020016000815260200160608152602001600081526020016000815260200160006001600160a01b03168152602001600081525090565b6000602082840312156136b457600080fd5b81356001600160e01b03198116811461323657600080fd5b600080604083850312156136df57600080fd5b50508035926020909101359150565b60008083601f84011261370057600080fd5b50813567ffffffffffffffff81111561371857600080fd5b60208301915083602082850101111561220457600080fd5b600080600080600080600060c0888a03121561374b57600080fd5b873596506020880135955060408801359450606088013567ffffffffffffffff81111561377757600080fd5b6137838a828b016136ee565b989b979a50959895979660808701359660a0013595509350505050565b6001600160a01b03811681146113a557600080fd5b60008060008060008060a087890312156137ce57600080fd5b863595506020870135945060408701356137e7816137a0565b935060608701359250608087013567ffffffffffffffff81111561380a57600080fd5b61381689828a016136ee565b979a9699509497509295939492505050565b60006020828403121561383a57600080fd5b5035919050565b60006020828403121561385357600080fd5b8135613236816137a0565b60008060008060008060008060c0898b03121561387a57600080fd5b8835975060208901359650604089013567ffffffffffffffff808211156138a057600080fd5b6138ac8c838d016136ee565b909850965060608b01359150808211156138c557600080fd5b506138d28b828c016136ee565b90955093505060808901356138e6816137a0565b8092505060a089013590509295985092959890939650565b6000806040838503121561391157600080fd5b823591506020830135613923816137a0565b809150509250929050565b6000806040838503121561394157600080fd5b823561394c816137a0565b91506020830135613923816137a0565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561398557600080fd5b8235613990816137a0565b9150602083013567ffffffffffffffff808211156139ad57600080fd5b818501915085601f8301126139c157600080fd5b8135818111156139d3576139d361395c565b604051601f8201601f19908116603f011681019083821181831017156139fb576139fb61395c565b81604052828152886020848701011115613a1457600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b80151581146113a557600080fd5b600080600060608486031215613a5957600080fd5b8335613a64816137a0565b92506020840135613a7481613a36565b929592945050506040919091013590565b6000806000806000806000806000806101008b8d031215613aa557600080fd5b8a35995060208b0135985060408b0135975060608b0135965060808b013567ffffffffffffffff80821115613ad957600080fd5b613ae58e838f016136ee565b909850965060a08d0135955060c08d0135915080821115613b0557600080fd5b50613b128d828e016136ee565b9150809450508092505060e08b013590509295989b9194979a5092959850565b600080600060608486031215613b4757600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052602160045260246000fd5b60028110613b8457613b84613b5e565b9052565b60005b83811015613ba3578181015183820152602001613b8b565b50506000910152565b60008151808452613bc4816020860160208601613b88565b601f01601f19169290920160200192915050565b6000610100613be8848451613b74565b6020830151602085015260018060a01b036040840151166040850152606083015160608501526080830151608085015260a08301518160a0860152613c2f82860182613bac565b91505060c083015160c085015260e083015160e08501528091505092915050565b6020815260006132366020830184613bd8565b60058110613b8457613b84613b5e565b6000610100613c82838c613c63565b896020840152886040840152806060840152613ca081840189613bac565b6080840197909752505060a08101939093526001600160a01b039190911660c083015260e090910152949350505050565b6000610100613ce0838c613b74565b89602084015260018060a01b03891660408401528760608401528660808401528060a0840152613d1281840187613bac565b60c0840195909552505060e001529695505050505050565b6000610100613d3a848451613c63565b60208301516020850152604083015160408501526060830151816060860152613d6582860182613bac565b6080858101519087015260a0808601519087015260c0808601516001600160a01b03169087015260e0948501519490950193909352509192915050565b604081526000613db56040830185613d2a565b82810360208401526133688185613bd8565b6020815260006132366020830184613d2a565b600060208284031215613dec57600080fd5b815161323681613a36565b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b6020808252600b908201526a125b9d985b1a590818da5960aa1b604082015260600190565b600181811c90821680613e5f57607f821691505b602082108103613e7f57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561123657600081815260208120601f850160051c81016020861015613eac5750805b601f850160051c820191505b81811015611dc957828155600101613eb8565b67ffffffffffffffff831115613ee357613ee361395c565b613ef783613ef18354613e4b565b83613e85565b6000601f841160018114613f2b5760008515613f135750838201355b600019600387901b1c1916600186901b178355613f85565b600083815260209020601f19861690835b82811015613f5c5786850135825560209485019460019092019101613f3c565b5086821015613f795760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b87815286602082015260c060408201526000613fd560c083018789613f8c565b606083019590955250608081019290925260a090910152949350505050565b85815260806020820152600061400e608083018688613f8c565b6001600160a01b0394909416604083015250606001529392505050565b634e487b7160e01b600052601160045260246000fd5b6000600182016140535761405361402b565b5060010190565b87815286602082015285604082015260c06060820152600061408060c083018688613f8c565b6001600160a01b039490941660808301525060a0015295945050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b815167ffffffffffffffff8111156141515761415161395c565b6141658161415f8454613e4b565b84613e85565b602080601f83116001811461419a57600084156141825750858301515b600019600386901b1c1916600185901b178555611dc9565b600085815260208120601f198616915b828110156141c9578886015182559484019460019091019084016141aa565b50858210156141e75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006101008b83528a60208401528060408401526142188184018a8c613f8c565b9150506142286060830188613b74565b8560808301528460a08301528360c08301528260e08301529a9950505050505050505050565b808202811582820484141761081d5761081d61402b565b60008261428257634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561429957600080fd5b5051919050565b6000602082840312156142b257600080fd5b8151613236816137a0565b6c6372656174655365727669636560981b815284600d820152603b60f81b602d82015283602e8201528183604e83013760009101604e019081529392505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8082018082111561081d5761081d61402b565b6d18dc99585d19541c9bdc1bdcd85b60921b815284600e820152603b60f81b602e82015283602f8201528183604f83013760009101604f019081529392505050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516143d6816017850160208801613b88565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351614407816028840160208801613b88565b01602801949350505050565b6020815260006132366020830184613bac565b634e487b7160e01b600052603260045260246000fd5b60008161444b5761444b61402b565b506000190190565b60008251614465818460208701613b88565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a1ba7d9ed8bda0e85592c39f8b8a90f379bcd674d0b9fd980896e2501b6dde2264736f6c63430008110033", - "deployedBytecode": "0x6080604052600436106102305760003560e01c80636ce76f301161012e578063b5735c1e116100ab578063d547741f1161006f578063d547741f1461072e578063ef0e239b1461074e578063f2fde38b1461077b578063f6c53d9b1461079b578063f9eaee0d146107b257600080fd5b8063b5735c1e1461064a578063c22c4f431461066a578063c2cfee271461069e578063ccaa7d2a146106d2578063d4eee1fc1461070057600080fd5b806391d14854116100f257806391d14854146105b5578063a217fddf146105d5578063a24bd889146105ea578063a7d5eaea146105fd578063aba210091461061d57600080fd5b80636ce76f30146104dc578063715018a61461051057806371da85f9146105255780637c5a72cd146105775780638da5cb5b1461059757600080fd5b80632afaf220116101bc5780633ca2ad6f116101805780633ca2ad6f1461043b578063485cc9551461045b5780634f1ef2861461047b57806352d1902d1461048e578063572b6c05146104a357600080fd5b80632afaf220146103a85780632f2ff15d146103bb57806336568abe146103db5780633659cfe6146103fb5780633751d89c1461041b57600080fd5b8063156b39aa11610203578063156b39aa146102e557806319de9d6c1461030a5780631db087ff1461032a578063248a9ca31461035857806326d006681461038857600080fd5b806301ffc9a714610235578063089b7c731461026a5780631499f9e61461028c578063154664ed146102c5575b600080fd5b34801561024157600080fd5b506102556102503660046136a2565b6107ec565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061028a6102853660046136cc565b610823565b005b34801561029857600080fd5b50610130546102ad906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b3480156102d157600080fd5b5061028a6102e0366004613730565b6109c6565b3480156102f157600080fd5b506102fc6101365481565b604051908152602001610261565b34801561031657600080fd5b5061028a6103253660046137b5565b610cde565b34801561033657600080fd5b506102fc610345366004613828565b6101336020526000908152604090205481565b34801561036457600080fd5b506102fc610373366004613828565b600090815260fc602052604090206001015490565b34801561039457600080fd5b5061028a6103a3366004613841565b610f83565b6102fc6103b636600461385e565b610fe6565b3480156103c757600080fd5b5061028a6103d63660046138fe565b611211565b3480156103e757600080fd5b5061028a6103f63660046138fe565b61123b565b34801561040757600080fd5b5061028a610416366004613841565b6112c9565b34801561042757600080fd5b5061028a610436366004613841565b6113a8565b34801561044757600080fd5b5061028a610456366004613828565b611401565b34801561046757600080fd5b5061028a61047636600461392e565b611449565b61028a610489366004613972565b6115c0565b34801561049a57600080fd5b506102fc61168c565b3480156104af57600080fd5b506102556104be366004613841565b6001600160a01b031660009081526065602052604090205460ff1690565b3480156104e857600080fd5b506102fc7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f81565b34801561051c57600080fd5b5061028a61173f565b34801561053157600080fd5b50610560610540366004613841565b610135602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610261565b34801561058357600080fd5b5061028a610592366004613a44565b611753565b3480156105a357600080fd5b506033546001600160a01b03166102ad565b3480156105c157600080fd5b506102556105d03660046138fe565b611828565b3480156105e157600080fd5b506102fc600081565b61028a6105f8366004613a85565b611853565b34801561060957600080fd5b5061028a610618366004613b32565b611b6d565b34801561062957600080fd5b5061063d6106383660046136cc565b611bef565b6040516102619190613c50565b34801561065657600080fd5b5061028a6106653660046136cc565b611d2c565b34801561067657600080fd5b5061068a610685366004613828565b611dd1565b604051610261989796959493929190613c73565b3480156106aa57600080fd5b506106be6106b93660046136cc565b611eae565b604051610261989796959493929190613cd1565b3480156106de57600080fd5b506102fc6106ed366004613828565b6101346020526000908152604090205481565b34801561070c57600080fd5b5061072061071b3660046136cc565b611f95565b604051610261929190613da2565b34801561073a57600080fd5b5061028a6107493660046138fe565b61220b565b34801561075a57600080fd5b5061076e610769366004613828565b612230565b6040516102619190613dc7565b34801561078757600080fd5b5061028a610796366004613841565b6123b0565b3480156107a757600080fd5b506102fc61012e5481565b3480156107be57600080fd5b506102556107cd366004613841565b6001600160a01b03166000908152610135602052604090205460ff1690565b60006001600160e01b03198216637965db0b60e01b148061081d57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61012f5482906001600160a01b0316632fa117e582610840612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561088a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ae9190613dda565b6108d35760405162461bcd60e51b81526004016108ca90613df7565b60405180910390fd5b600082815261013160205260409020600181015484146109255760405162461bcd60e51b815260206004820152600d60248201526c3737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff16600481111561093d5761093d613b5e565b146109825760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b805460ff191660031781556040518381527f853aa4be1ac86f37acfc91d42b57f1fe895205aa6f8f9b7caa77ca257049ab1a9060200160405180910390a150505050565b61012f5487906001600160a01b0316632fa117e5826109e3612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a519190613dda565b610a6d5760405162461bcd60e51b81526004016108ca90613df7565b60008781526101316020908152604080832061013283528184208c855290925282209091825460ff166004811115610aa757610aa7613b5e565b14610ae95760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b89816001015414610b2c5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b602e8614610b4c5760405162461bcd60e51b81526004016108ca90613e26565b6001815460ff166001811115610b6457610b64613b5e565b03610ba55760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481d985b1a59185d1959607a1b60448201526064016108ca565b60068201546001600160a01b031660009081526101356020526040902060010154881015610c065760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b8315610c695761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015610c5057600080fd5b505afa158015610c64573d6000803e3d6000fd5b505050505b6003810188905560058101610c7f878983613ecb565b5060068101859055600781018490556040517ffbfaa6f4e508bec40137ac265a7424e16a2d209355b2f4a35de5a80ba8fec1db90610cca908b908d908b908b908e908c908c90613fb5565b60405180910390a150505050505050505050565b61012f5486906001600160a01b0316632fa117e582610cfb612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610d45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d699190613dda565b610d855760405162461bcd60e51b81526004016108ca90613df7565b60008681526101316020526040902060018101548814610dd75760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff166004811115610def57610def613b5e565b14610e345760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b602e8314610e545760405162461bcd60e51b81526004016108ca90613e26565b6001600160a01b0386166000908152610135602052604090205460ff16610eb15760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108ca565b8060070154851015610f055760405162461bcd60e51b815260206004820152601c60248201527f43616e27742072656475636520726566657272616c20616d6f756e740000000060448201526064016108ca565b60038101610f14848683613ecb565b50600781018590556006810180546001600160a01b0319166001600160a01b0388161790556040517f79dba2b7507f91f38c9a67e52f174c234541b20eccc91ad6afe9d3753f6371f590610f71908990879087908b908b90613ff4565b60405180910390a15050505050505050565b610f8b612435565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b61012f5460009089906001600160a01b0316632fa117e582611006612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611050573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110749190613dda565b6110905760405162461bcd60e51b81526004016108ca90613df7565b61109f8a8a8a8a8a8a8a6124ae565b61012e805490819060006110b283614041565b9091555050600081815261013160205260409020805460ff19168155600181018c9055600381016110e48a8c83613ecb565b50600581018b90556006810180546001600160a01b0319166001600160a01b0388161790556007810185905560008c8152610133602052604090205415801561113a575060008c81526101346020526040902054155b1561119f5761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b15801561118657600080fd5b505af115801561119a573d6000803e3d6000fd5b505050505b60008c8152610133602052604081208054916111ba83614041565b91905055507fe7f6435fc92b0ccd6f56395ae67b06f2cdb9680c0179f87f5821431304ad3f3e828d8d8d8d8b8b6040516111fa979695949392919061405a565b60405180910390a1509a9950505050505050505050565b600082815260fc602052604090206001015461122c816126b7565b61123683836126c8565b505050565b611243612426565b6001600160a01b0316816001600160a01b0316146112bb5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108ca565b6112c5828261274f565b5050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036113115760405162461bcd60e51b81526004016108ca9061409f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661135a600080516020614470833981519152546001600160a01b031690565b6001600160a01b0316146113805760405162461bcd60e51b81526004016108ca906140eb565b611389816127d4565b604080516000808252602082019092526113a5918391906127dc565b50565b6113b0612435565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee69101610fdb565b600061140c816126b7565b6101368290556040518281527f577d7afcf67637a2f602cba220bbb292c1d715380dd011bfec748c3f641b2fd29060200160405180910390a15050565b600054610100900460ff16158080156114695750600054600160ff909116105b806114835750303b158015611483575060005460ff166001145b6114e65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108ca565b6000805460ff191660011790558015611509576000805461ff0019166101001790555b611511612947565b611519612976565b611521612976565b611533600061152e612426565b61299d565b61012f80546001600160a01b038086166001600160a01b031992831617909255610130805492851692909116919091179055600161012e55611575601e611401565b8015611236576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036116085760405162461bcd60e51b81526004016108ca9061409f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611651600080516020614470833981519152546001600160a01b031690565b6001600160a01b0316146116775760405162461bcd60e51b81526004016108ca906140eb565b611680826127d4565b6112c5828260016127dc565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461172c5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108ca565b5060008051602061447083398151915290565b611747612435565b61175160006129a7565b565b61175b612435565b6001600160a01b038316158015611770575081155b156117bd5760405162461bcd60e51b815260206004820152601d60248201527f4f776e65722063616e27742072656d6f7665204f78206164647265737300000060448201526064016108ca565b6001600160a01b03831660008181526101356020908152604091829020805460ff19168615159081178255600190910185905582519384529083015281018290527f42b585a1da1cff4b571e7a78aea1b4601b1d128de41a0feebd8a77aaf48b9d88906060016115b3565b600091825260fc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61012f548a906001600160a01b0316632fa117e582611870612426565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156118ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118de9190613dda565b6118fa5760405162461bcd60e51b81526004016108ca90613df7565b60008a81526101316020526040902061191a8c8c8c8c8c8c8b8b8b6129f9565b60408051610100810182526000815260208082018f905260068401546001600160a01b031682840152606082018d9052608082018c90528251601f8b01829004820281018201909352898352909160a08301918b908b9081908401838280828437600081840152601f19601f8201169050808301925050505050505081526020018781526020018481525061013260008d815260200190815260200160002060008e815260200190815260200160002060008201518160000160006101000a81548160ff021916908360018111156119f4576119f4613b5e565b02179055506020820151600182015560408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a08201516005820190611a519082614137565b5060c0820151600682015560e09091015160079091015560008c81526101336020526040902054158015611a92575060008c81526101346020526040902054155b15611af75761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015611ade57600080fd5b505af1158015611af2573d6000803e3d6000fd5b505050505b60008c815261013460205260408120805491611b1283614041565b91905055507fabd26455c3256ad90125661f4c1a4c16fecf585ccade21e749c56d8fd44bb1dd8b8d8a8a60008f8f8d8b604051611b57999897969594939291906141f7565b60405180910390a1505050505050505050505050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611b97816126b7565b60008481526101316020908152604080832061013283528184208785529092529091208154600160ff1991821681178455808301546002850155600484018690558254909183911682805b0217905550505050505050565b611bf7613604565b60008381526101326020908152604080832085845290915290819020815161010081019092528054829060ff166001811115611c3557611c35613b5e565b6001811115611c4657611c46613b5e565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611c8e90613e4b565b80601f0160208091040260200160405190810160405280929190818152602001828054611cba90613e4b565b8015611d075780601f10611cdc57610100808354040283529160200191611d07565b820191906000526020600020905b815481529060010190602001808311611cea57829003601f168201915b5050505050815260200160068201548152602001600782015481525050905092915050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611d56816126b7565b6000838152610131602090815260408083206101328352818420600282015485529092528220600381015491929091611d9086606461424e565b611d9a9190614265565b9050610136548110611db657825460ff19166002178355611dc9565b8254600490849060ff1916600183611be2565b505050505050565b61013160205260009081526040902080546001820154600283015460038401805460ff909416949293919291611e0690613e4b565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3290613e4b565b8015611e7f5780601f10611e5457610100808354040283529160200191611e7f565b820191906000526020600020905b815481529060010190602001808311611e6257829003601f168201915b505050600484015460058501546006860154600790960154949591949093506001600160a01b03909116915088565b61013260209081526000928352604080842090915290825290208054600182015460028301546003840154600485015460058601805460ff9096169694956001600160a01b03909416949293919291611f0690613e4b565b80601f0160208091040260200160405190810160405280929190818152602001828054611f3290613e4b565b8015611f7f5780601f10611f5457610100808354040283529160200191611f7f565b820191906000526020600020905b815481529060010190602001808311611f6257829003601f168201915b5050505050908060060154908060070154905088565b611f9d613653565b611fa5613604565b60008481526101316020526040808220815161010081019092528054829060ff166004811115611fd757611fd7613b5e565b6004811115611fe857611fe8613b5e565b8152602001600182015481526020016002820154815260200160038201805461201090613e4b565b80601f016020809104026020016040519081016040528092919081815260200182805461203c90613e4b565b80156120895780601f1061205e57610100808354040283529160200191612089565b820191906000526020600020905b81548152906001019060200180831161206c57829003601f168201915b50505091835250506004820154602080830191909152600583015460408084019190915260068401546001600160a01b03166060840152600790930154608090920191909152600088815261013282528281208882529091528181208251610100810190935280549394509092829060ff16600181111561210c5761210c613b5e565b600181111561211d5761211d613b5e565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a09092019161216590613e4b565b80601f016020809104026020016040519081016040528092919081815260200182805461219190613e4b565b80156121de5780601f106121b3576101008083540402835291602001916121de565b820191906000526020600020905b8154815290600101906020018083116121c157829003601f168201915b505050918352505060068201546020820152600790910154604090910152919350909150505b9250929050565b600082815260fc6020526040902060010154612226816126b7565b611236838361274f565b612238613653565b61012e54821061228a5760405162461bcd60e51b815260206004820152601a60248201527f54686973207365727669636520646f65736e277420657869737400000000000060448201526064016108ca565b6000828152610131602052604090819020815161010081019092528054829060ff1660048111156122bd576122bd613b5e565b60048111156122ce576122ce613b5e565b815260200160018201548152602001600282015481526020016003820180546122f690613e4b565b80601f016020809104026020016040519081016040528092919081815260200182805461232290613e4b565b801561236f5780601f106123445761010080835404028352916020019161236f565b820191906000526020600020905b81548152906001019060200180831161235257829003601f168201915b5050509183525050600482015460208201526005820154604082015260068201546001600160a01b0316606082015260079091015460809091015292915050565b6123b8612435565b6001600160a01b03811661241d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108ca565b6113a5816129a7565b6000612430612de0565b905090565b61243d612426565b6001600160a01b03166124586033546001600160a01b031690565b6001600160a01b0316146117515760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108ca565b61013054604051638a98636360e01b8152600481018890526000916001600160a01b031690638a98636390602401602060405180830381865afa1580156124f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061251d9190614287565b90508034146125635760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b602e85146125835760405162461bcd60e51b81526004016108ca90613e26565b6001600160a01b0382166000908152610135602052604090205460ff166125e05760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108ca565b61013054604051631fff7f2760e11b8152600481018990526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa15801561262b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264f91906142a0565b90506001600160a01b038116156126ac57600089815261013360209081526040808320549051612686928d92918c918c91016142bd565b6040516020818303038152906040528051906020012090506126aa86868385612e19565b505b505050505050505050565b6113a5816126c3612426565b612f0d565b6126d28282611828565b6112c557600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561270b612426565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6127598282611828565b156112c557600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff19169055612790612426565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6113a5612435565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561280f5761123683612f66565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612869575060408051601f3d908101601f1916820190925261286691810190614287565b60015b6128cc5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108ca565b600080516020614470833981519152811461293b5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108ca565b50611236838383613002565b600054610100900460ff1661296e5760405162461bcd60e51b81526004016108ca906142fe565b61175161302d565b600054610100900460ff166117515760405162461bcd60e51b81526004016108ca906142fe565b6112c582826126c8565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61013054604051634a7ab1d560e01b8152600481018890526000916001600160a01b031690634a7ab1d590602401602060405180830381865afa158015612a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a689190614287565b9050803414612aae5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b60008981526101316020908152604080832060068101546001600160a01b03168452610135909252909120600101546007820154612aec908b614349565b1015612b2b5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b6000815460ff166004811115612b4357612b43613b5e565b14612b855760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b8060010154600003612bcd5760405162461bcd60e51b815260206004820152601160248201527014d95c9d9a58d9481b9bdd08195e1a5cdd607a1b60448201526064016108ca565b60008a8152610132602090815260408083208e84529091529020600101548b9003612c335760405162461bcd60e51b81526020600482015260166024820152751c1c9bdc1bdcd85b08185b1c9958591e48195e1a5cdd60521b60448201526064016108ca565b8a816001015403612c905760405162461bcd60e51b815260206004820152602160248201527f63616e27742063726561746520666f7220796f7572206f776e207365727669636044820152606560f81b60648201526084016108ca565b602e8614612cb05760405162461bcd60e51b81526004016108ca90613e26565b61013054604051631fff7f2760e11b8152600481018a90526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612cfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d1f91906142a0565b90506001600160a01b03811615612d6f5760008c8c8a8a604051602001612d49949392919061435c565b604051602081830303815290604052805190602001209050612d6d87878385612e19565b505b8315612dd25761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015612db957600080fd5b505afa158015612dcd573d6000803e3d6000fd5b505050505b505050505050505050505050565b600060143610801590612e0257503360009081526065602052604090205460ff165b15612e14575060131936013560601c90565b503390565b6000612e72836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000612eb68287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061306492505050565b9050806001600160a01b0316836001600160a01b031614611dc95760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064016108ca565b612f178282611828565b6112c557612f2481613088565b612f2f83602061309a565b604051602001612f4092919061439e565b60408051601f198184030181529082905262461bcd60e51b82526108ca91600401614413565b6001600160a01b0381163b612fd35760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108ca565b60008051602061447083398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61300b8361323d565b6000825111806130185750805b1561123657613027838361327d565b50505050565b600054610100900460ff166130545760405162461bcd60e51b81526004016108ca906142fe565b61175161305f612426565b6129a7565b60008060006130738585613371565b91509150613080816133b3565b509392505050565b606061081d6001600160a01b03831660145b606060006130a983600261424e565b6130b4906002614349565b67ffffffffffffffff8111156130cc576130cc61395c565b6040519080825280601f01601f1916602001820160405280156130f6576020820181803683370190505b509050600360fc1b8160008151811061311157613111614426565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061314057613140614426565b60200101906001600160f81b031916908160001a905350600061316484600261424e565b61316f906001614349565b90505b60018111156131e7576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106131a3576131a3614426565b1a60f81b8282815181106131b9576131b9614426565b60200101906001600160f81b031916908160001a90535060049490941c936131e08161443c565b9050613172565b5083156132365760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108ca565b9392505050565b61324681612f66565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6132e55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108ca565b600080846001600160a01b0316846040516133009190614453565b600060405180830381855af49150503d806000811461333b576040519150601f19603f3d011682016040523d82523d6000602084013e613340565b606091505b50915091506133688282604051806060016040528060278152602001614490602791396134fd565b95945050505050565b60008082516041036133a75760208301516040840151606085015160001a61339b87828585613516565b94509450505050612204565b50600090506002612204565b60008160048111156133c7576133c7613b5e565b036133cf5750565b60018160048111156133e3576133e3613b5e565b036134305760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108ca565b600281600481111561344457613444613b5e565b036134915760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108ca565b60038160048111156134a5576134a5613b5e565b036113a55760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108ca565b6060831561350c575081613236565b61323683836135da565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561354d57506000905060036135d1565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156135a1573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166135ca576000600192509250506135d1565b9150600090505b94509492505050565b8151156135ea5781518083602001fd5b8060405162461bcd60e51b81526004016108ca9190614413565b60408051610100810190915280600081526020016000815260200160006001600160a01b0316815260200160008152602001600081526020016060815260200160008152602001600081525090565b6040805161010081019091528060008152602001600081526020016000815260200160608152602001600081526020016000815260200160006001600160a01b03168152602001600081525090565b6000602082840312156136b457600080fd5b81356001600160e01b03198116811461323657600080fd5b600080604083850312156136df57600080fd5b50508035926020909101359150565b60008083601f84011261370057600080fd5b50813567ffffffffffffffff81111561371857600080fd5b60208301915083602082850101111561220457600080fd5b600080600080600080600060c0888a03121561374b57600080fd5b873596506020880135955060408801359450606088013567ffffffffffffffff81111561377757600080fd5b6137838a828b016136ee565b989b979a50959895979660808701359660a0013595509350505050565b6001600160a01b03811681146113a557600080fd5b60008060008060008060a087890312156137ce57600080fd5b863595506020870135945060408701356137e7816137a0565b935060608701359250608087013567ffffffffffffffff81111561380a57600080fd5b61381689828a016136ee565b979a9699509497509295939492505050565b60006020828403121561383a57600080fd5b5035919050565b60006020828403121561385357600080fd5b8135613236816137a0565b60008060008060008060008060c0898b03121561387a57600080fd5b8835975060208901359650604089013567ffffffffffffffff808211156138a057600080fd5b6138ac8c838d016136ee565b909850965060608b01359150808211156138c557600080fd5b506138d28b828c016136ee565b90955093505060808901356138e6816137a0565b8092505060a089013590509295985092959890939650565b6000806040838503121561391157600080fd5b823591506020830135613923816137a0565b809150509250929050565b6000806040838503121561394157600080fd5b823561394c816137a0565b91506020830135613923816137a0565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561398557600080fd5b8235613990816137a0565b9150602083013567ffffffffffffffff808211156139ad57600080fd5b818501915085601f8301126139c157600080fd5b8135818111156139d3576139d361395c565b604051601f8201601f19908116603f011681019083821181831017156139fb576139fb61395c565b81604052828152886020848701011115613a1457600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b80151581146113a557600080fd5b600080600060608486031215613a5957600080fd5b8335613a64816137a0565b92506020840135613a7481613a36565b929592945050506040919091013590565b6000806000806000806000806000806101008b8d031215613aa557600080fd5b8a35995060208b0135985060408b0135975060608b0135965060808b013567ffffffffffffffff80821115613ad957600080fd5b613ae58e838f016136ee565b909850965060a08d0135955060c08d0135915080821115613b0557600080fd5b50613b128d828e016136ee565b9150809450508092505060e08b013590509295989b9194979a5092959850565b600080600060608486031215613b4757600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052602160045260246000fd5b60028110613b8457613b84613b5e565b9052565b60005b83811015613ba3578181015183820152602001613b8b565b50506000910152565b60008151808452613bc4816020860160208601613b88565b601f01601f19169290920160200192915050565b6000610100613be8848451613b74565b6020830151602085015260018060a01b036040840151166040850152606083015160608501526080830151608085015260a08301518160a0860152613c2f82860182613bac565b91505060c083015160c085015260e083015160e08501528091505092915050565b6020815260006132366020830184613bd8565b60058110613b8457613b84613b5e565b6000610100613c82838c613c63565b896020840152886040840152806060840152613ca081840189613bac565b6080840197909752505060a08101939093526001600160a01b039190911660c083015260e090910152949350505050565b6000610100613ce0838c613b74565b89602084015260018060a01b03891660408401528760608401528660808401528060a0840152613d1281840187613bac565b60c0840195909552505060e001529695505050505050565b6000610100613d3a848451613c63565b60208301516020850152604083015160408501526060830151816060860152613d6582860182613bac565b6080858101519087015260a0808601519087015260c0808601516001600160a01b03169087015260e0948501519490950193909352509192915050565b604081526000613db56040830185613d2a565b82810360208401526133688185613bd8565b6020815260006132366020830184613d2a565b600060208284031215613dec57600080fd5b815161323681613a36565b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b6020808252600b908201526a125b9d985b1a590818da5960aa1b604082015260600190565b600181811c90821680613e5f57607f821691505b602082108103613e7f57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561123657600081815260208120601f850160051c81016020861015613eac5750805b601f850160051c820191505b81811015611dc957828155600101613eb8565b67ffffffffffffffff831115613ee357613ee361395c565b613ef783613ef18354613e4b565b83613e85565b6000601f841160018114613f2b5760008515613f135750838201355b600019600387901b1c1916600186901b178355613f85565b600083815260209020601f19861690835b82811015613f5c5786850135825560209485019460019092019101613f3c565b5086821015613f795760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b87815286602082015260c060408201526000613fd560c083018789613f8c565b606083019590955250608081019290925260a090910152949350505050565b85815260806020820152600061400e608083018688613f8c565b6001600160a01b0394909416604083015250606001529392505050565b634e487b7160e01b600052601160045260246000fd5b6000600182016140535761405361402b565b5060010190565b87815286602082015285604082015260c06060820152600061408060c083018688613f8c565b6001600160a01b039490941660808301525060a0015295945050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b815167ffffffffffffffff8111156141515761415161395c565b6141658161415f8454613e4b565b84613e85565b602080601f83116001811461419a57600084156141825750858301515b600019600386901b1c1916600185901b178555611dc9565b600085815260208120601f198616915b828110156141c9578886015182559484019460019091019084016141aa565b50858210156141e75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006101008b83528a60208401528060408401526142188184018a8c613f8c565b9150506142286060830188613b74565b8560808301528460a08301528360c08301528260e08301529a9950505050505050505050565b808202811582820484141761081d5761081d61402b565b60008261428257634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561429957600080fd5b5051919050565b6000602082840312156142b257600080fd5b8151613236816137a0565b6c6372656174655365727669636560981b815284600d820152603b60f81b602d82015283602e8201528183604e83013760009101604e019081529392505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8082018082111561081d5761081d61402b565b6d18dc99585d19541c9bdc1bdcd85b60921b815284600e820152603b60f81b602e82015283602f8201528183604f83013760009101604f019081529392505050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516143d6816017850160208801613b88565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351614407816028840160208801613b88565b01602801949350505050565b6020815260006132366020830184613bac565b634e487b7160e01b600052603260045260246000fd5b60008161444b5761444b61402b565b506000190190565b60008251614465818460208701613b88565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a1ba7d9ed8bda0e85592c39f8b8a90f379bcd674d0b9fd980896e2501b6dde2264736f6c63430008110033", + "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b60805161469e620001206000396000818161102e0152818161106e015281816113250152818161136501526113f4015261469e6000f3fe6080604052600436106102305760003560e01c8063715018a61161012e578063c22c4f43116100ab578063ef0e239b1161006f578063ef0e239b1461072e578063f2fde38b1461075b578063f6c53d9b1461077b578063f9eaee0d14610792578063ff420375146107cc57600080fd5b8063c22c4f431461064a578063c2cfee271461067e578063ccaa7d2a146106b2578063d4eee1fc146106e0578063d547741f1461070e57600080fd5b8063a217fddf116100f2578063a217fddf146105b5578063a24bd889146105ca578063a7d5eaea146105dd578063aba21009146105fd578063b5735c1e1461062a57600080fd5b8063715018a6146104f057806371da85f9146105055780637c5a72cd146105575780638da5cb5b1461057757806391d148541461059557600080fd5b80632f2ff15d116101bc578063485cc95511610180578063485cc9551461043b5780634f1ef2861461045b57806352d1902d1461046e578063572b6c05146104835780636ce76f30146104bc57600080fd5b80632f2ff15d1461039b57806336568abe146103bb5780633659cfe6146103db5780633751d89c146103fb5780633ca2ad6f1461041b57600080fd5b8063156b39aa11610203578063156b39aa146102e55780631db087ff1461030a578063248a9ca31461033857806326d00668146103685780632afaf2201461038857600080fd5b806301ffc9a714610235578063089b7c731461026a5780631499f9e61461028c578063154664ed146102c5575b600080fd5b34801561024157600080fd5b50610255610250366004613872565b6107ec565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061028a61028536600461389c565b610823565b005b34801561029857600080fd5b50610130546102ad906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b3480156102d157600080fd5b5061028a6102e0366004613900565b6109c6565b3480156102f157600080fd5b506102fc6101365481565b604051908152602001610261565b34801561031657600080fd5b506102fc610325366004613970565b6101336020526000908152604090205481565b34801561034457600080fd5b506102fc610353366004613970565b600090815260fc602052604090206001015490565b34801561037457600080fd5b5061028a61038336600461399e565b610cde565b6102fc6103963660046139bb565b610d41565b3480156103a757600080fd5b5061028a6103b6366004613a5b565b610f6c565b3480156103c757600080fd5b5061028a6103d6366004613a5b565b610f96565b3480156103e757600080fd5b5061028a6103f636600461399e565b611024565b34801561040757600080fd5b5061028a61041636600461399e565b611103565b34801561042757600080fd5b5061028a610436366004613970565b61115c565b34801561044757600080fd5b5061028a610456366004613a8b565b6111a4565b61028a610469366004613acf565b61131b565b34801561047a57600080fd5b506102fc6113e7565b34801561048f57600080fd5b5061025561049e36600461399e565b6001600160a01b031660009081526065602052604090205460ff1690565b3480156104c857600080fd5b506102fc7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f81565b3480156104fc57600080fd5b5061028a61149a565b34801561051157600080fd5b5061054061052036600461399e565b610135602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610261565b34801561056357600080fd5b5061028a610572366004613ba1565b6114ae565b34801561058357600080fd5b506033546001600160a01b03166102ad565b3480156105a157600080fd5b506102556105b0366004613a5b565b611583565b3480156105c157600080fd5b506102fc600081565b61028a6105d8366004613be2565b6115ae565b3480156105e957600080fd5b5061028a6105f8366004613c8f565b6119dc565b34801561060957600080fd5b5061061d61061836600461389c565b611a5e565b6040516102619190613dad565b34801561063657600080fd5b5061028a61064536600461389c565b611b9b565b34801561065657600080fd5b5061066a610665366004613970565b611c40565b604051610261989796959493929190613dd0565b34801561068a57600080fd5b5061069e61069936600461389c565b611d1d565b604051610261989796959493929190613e2e565b3480156106be57600080fd5b506102fc6106cd366004613970565b6101346020526000908152604090205481565b3480156106ec57600080fd5b506107006106fb36600461389c565b611e04565b604051610261929190613eff565b34801561071a57600080fd5b5061028a610729366004613a5b565b61207a565b34801561073a57600080fd5b5061074e610749366004613970565b61209f565b6040516102619190613f24565b34801561076757600080fd5b5061028a61077636600461399e565b61221f565b34801561078757600080fd5b506102fc61012e5481565b34801561079e57600080fd5b506102556107ad36600461399e565b6001600160a01b03166000908152610135602052604090205460ff1690565b3480156107d857600080fd5b5061028a6107e7366004613f37565b612295565b60006001600160e01b03198216637965db0b60e01b148061081d57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61012f5482906001600160a01b0316632fa117e5826108406124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561088a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ae9190613f98565b6108d35760405162461bcd60e51b81526004016108ca90613fb5565b60405180910390fd5b600082815261013160205260409020600181015484146109255760405162461bcd60e51b815260206004820152600d60248201526c3737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff16600481111561093d5761093d613cbb565b146109825760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b805460ff191660031781556040518381527f853aa4be1ac86f37acfc91d42b57f1fe895205aa6f8f9b7caa77ca257049ab1a9060200160405180910390a150505050565b61012f5487906001600160a01b0316632fa117e5826109e36124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a519190613f98565b610a6d5760405162461bcd60e51b81526004016108ca90613fb5565b60008781526101316020908152604080832061013283528184208c855290925282209091825460ff166004811115610aa757610aa7613cbb565b14610ae95760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b89816001015414610b2c5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b602e8614610b4c5760405162461bcd60e51b81526004016108ca90613fe4565b6001815460ff166001811115610b6457610b64613cbb565b03610ba55760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481d985b1a59185d1959607a1b60448201526064016108ca565b60068201546001600160a01b031660009081526101356020526040902060010154881015610c065760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b8315610c695761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015610c5057600080fd5b505afa158015610c64573d6000803e3d6000fd5b505050505b6003810188905560058101610c7f878983614089565b5060068101859055600781018490556040517ffbfaa6f4e508bec40137ac265a7424e16a2d209355b2f4a35de5a80ba8fec1db90610cca908b908d908b908b908e908c908c90614173565b60405180910390a150505050505050505050565b610ce66124cc565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b61012f5460009089906001600160a01b0316632fa117e582610d616124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610dab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcf9190613f98565b610deb5760405162461bcd60e51b81526004016108ca90613fb5565b610dfa8a8a8a8a8a8a8a612545565b61012e80549081906000610e0d836141c8565b9091555050600081815261013160205260409020805460ff19168155600181018c905560038101610e3f8a8c83614089565b50600581018b90556006810180546001600160a01b0319166001600160a01b0388161790556007810185905560008c81526101336020526040902054158015610e95575060008c81526101346020526040902054155b15610efa5761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015610ee157600080fd5b505af1158015610ef5573d6000803e3d6000fd5b505050505b60008c815261013360205260408120805491610f15836141c8565b91905055507fe7f6435fc92b0ccd6f56395ae67b06f2cdb9680c0179f87f5821431304ad3f3e828d8d8d8d8b8b604051610f5597969594939291906141e1565b60405180910390a1509a9950505050505050505050565b600082815260fc6020526040902060010154610f878161274e565b610f91838361275f565b505050565b610f9e6124bd565b6001600160a01b0316816001600160a01b0316146110165760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108ca565b61102082826127e6565b5050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361106c5760405162461bcd60e51b81526004016108ca90614226565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166110b5600080516020614622833981519152546001600160a01b031690565b6001600160a01b0316146110db5760405162461bcd60e51b81526004016108ca90614272565b6110e48161286b565b6040805160008082526020820190925261110091839190612873565b50565b61110b6124cc565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee69101610d36565b60006111678161274e565b6101368290556040518281527f577d7afcf67637a2f602cba220bbb292c1d715380dd011bfec748c3f641b2fd29060200160405180910390a15050565b600054610100900460ff16158080156111c45750600054600160ff909116105b806111de5750303b1580156111de575060005460ff166001145b6112415760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108ca565b6000805460ff191660011790558015611264576000805461ff0019166101001790555b61126c6129de565b611274612a0d565b61127c612a0d565b61128e60006112896124bd565b612a34565b61012f80546001600160a01b038086166001600160a01b031992831617909255610130805492851692909116919091179055600161012e556112d0601e61115c565b8015610f91576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036113635760405162461bcd60e51b81526004016108ca90614226565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166113ac600080516020614622833981519152546001600160a01b031690565b6001600160a01b0316146113d25760405162461bcd60e51b81526004016108ca90614272565b6113db8261286b565b61102082826001612873565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146114875760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108ca565b5060008051602061462283398151915290565b6114a26124cc565b6114ac6000612a3e565b565b6114b66124cc565b6001600160a01b0383161580156114cb575081155b156115185760405162461bcd60e51b815260206004820152601d60248201527f4f776e65722063616e27742072656d6f7665204f78206164647265737300000060448201526064016108ca565b6001600160a01b03831660008181526101356020908152604091829020805460ff19168615159081178255600190910185905582519384529083015281018290527f42b585a1da1cff4b571e7a78aea1b4601b1d128de41a0feebd8a77aaf48b9d889060600161130e565b600091825260fc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61012f548a906001600160a01b0316632fa117e5826115cb6124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611615573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116399190613f98565b6116555760405162461bcd60e51b81526004016108ca90613fb5565b60008a81526101316020526040808220815161010081019092528054829060ff16600481111561168757611687613cbb565b600481111561169857611698613cbb565b815260200160018201548152602001600282015481526020016003820180546116c090614009565b80601f01602080910402602001604051908101604052809291908181526020018280546116ec90614009565b80156117395780601f1061170e57610100808354040283529160200191611739565b820191906000526020600020905b81548152906001019060200180831161171c57829003601f168201915b5050509183525050600482015460208201526005820154604082015260068201546001600160a01b0316606082015260079091015460809091015290506117878c8c8c8c8c8c8b8b8b612a90565b60408051610100810190915280600081526020018d81526020018260c001516001600160a01b031681526020018b81526020018a815260200189898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020018781526020018481525061013260008d815260200190815260200160002060008e815260200190815260200160002060008201518160000160006101000a81548160ff0219169083600181111561186357611863613cbb565b02179055506020820151600182015560408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a082015160058201906118c090826142be565b5060c0820151600682015560e09091015160079091015560008c81526101336020526040902054158015611901575060008c81526101346020526040902054155b156119665761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b15801561194d57600080fd5b505af1158015611961573d6000803e3d6000fd5b505050505b60008c815261013460205260408120805491611981836141c8565b91905055507fabd26455c3256ad90125661f4c1a4c16fecf585ccade21e749c56d8fd44bb1dd8b8d8a8a60008f8f8d8b6040516119c69998979695949392919061437e565b60405180910390a1505050505050505050505050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611a068161274e565b60008481526101316020908152604080832061013283528184208785529092529091208154600160ff1991821681178455808301546002850155600484018690558254909183911682805b0217905550505050505050565b611a666137d4565b60008381526101326020908152604080832085845290915290819020815161010081019092528054829060ff166001811115611aa457611aa4613cbb565b6001811115611ab557611ab5613cbb565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611afd90614009565b80601f0160208091040260200160405190810160405280929190818152602001828054611b2990614009565b8015611b765780601f10611b4b57610100808354040283529160200191611b76565b820191906000526020600020905b815481529060010190602001808311611b5957829003601f168201915b5050505050815260200160068201548152602001600782015481525050905092915050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611bc58161274e565b6000838152610131602090815260408083206101328352818420600282015485529092528220600381015491929091611bff8660646143d5565b611c0991906143ec565b9050610136548110611c2557825460ff19166002178355611c38565b8254600490849060ff1916600183611a51565b505050505050565b61013160205260009081526040902080546001820154600283015460038401805460ff909416949293919291611c7590614009565b80601f0160208091040260200160405190810160405280929190818152602001828054611ca190614009565b8015611cee5780601f10611cc357610100808354040283529160200191611cee565b820191906000526020600020905b815481529060010190602001808311611cd157829003601f168201915b505050600484015460058501546006860154600790960154949591949093506001600160a01b03909116915088565b61013260209081526000928352604080842090915290825290208054600182015460028301546003840154600485015460058601805460ff9096169694956001600160a01b03909416949293919291611d7590614009565b80601f0160208091040260200160405190810160405280929190818152602001828054611da190614009565b8015611dee5780601f10611dc357610100808354040283529160200191611dee565b820191906000526020600020905b815481529060010190602001808311611dd157829003601f168201915b5050505050908060060154908060070154905088565b611e0c613823565b611e146137d4565b60008481526101316020526040808220815161010081019092528054829060ff166004811115611e4657611e46613cbb565b6004811115611e5757611e57613cbb565b81526020016001820154815260200160028201548152602001600382018054611e7f90614009565b80601f0160208091040260200160405190810160405280929190818152602001828054611eab90614009565b8015611ef85780601f10611ecd57610100808354040283529160200191611ef8565b820191906000526020600020905b815481529060010190602001808311611edb57829003601f168201915b50505091835250506004820154602080830191909152600583015460408084019190915260068401546001600160a01b03166060840152600790930154608090920191909152600088815261013282528281208882529091528181208251610100810190935280549394509092829060ff166001811115611f7b57611f7b613cbb565b6001811115611f8c57611f8c613cbb565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611fd490614009565b80601f016020809104026020016040519081016040528092919081815260200182805461200090614009565b801561204d5780601f106120225761010080835404028352916020019161204d565b820191906000526020600020905b81548152906001019060200180831161203057829003601f168201915b505050918352505060068201546020820152600790910154604090910152919350909150505b9250929050565b600082815260fc60205260409020600101546120958161274e565b610f9183836127e6565b6120a7613823565b61012e5482106120f95760405162461bcd60e51b815260206004820152601a60248201527f54686973207365727669636520646f65736e277420657869737400000000000060448201526064016108ca565b6000828152610131602052604090819020815161010081019092528054829060ff16600481111561212c5761212c613cbb565b600481111561213d5761213d613cbb565b8152602001600182015481526020016002820154815260200160038201805461216590614009565b80601f016020809104026020016040519081016040528092919081815260200182805461219190614009565b80156121de5780601f106121b3576101008083540402835291602001916121de565b820191906000526020600020905b8154815290600101906020018083116121c157829003601f168201915b5050509183525050600482015460208201526005820154604082015260068201546001600160a01b0316606082015260079091015460809091015292915050565b6122276124cc565b6001600160a01b03811661228c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108ca565b61110081612a3e565b61012f5485906001600160a01b0316632fa117e5826122b26124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156122fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123209190613f98565b61233c5760405162461bcd60e51b81526004016108ca90613fb5565b6000858152610131602052604090206001810154871461238e5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff1660048111156123a6576123a6613cbb565b146123eb5760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b602e831461240b5760405162461bcd60e51b81526004016108ca90613fe4565b806007015485101561245f5760405162461bcd60e51b815260206004820152601c60248201527f43616e27742072656475636520726566657272616c20616d6f756e740000000060448201526064016108ca565b6003810161246e848683614089565b50600781018590556040517fae55ce3c351e2400a1a143e7ed66668e581e1656ad1797a317e415d035880916906124ac908890879087908a9061440e565b60405180910390a150505050505050565b60006124c7612fb0565b905090565b6124d46124bd565b6001600160a01b03166124ef6033546001600160a01b031690565b6001600160a01b0316146114ac5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108ca565b61013054604051638a98636360e01b8152600481018890526000916001600160a01b031690638a98636390602401602060405180830381865afa158015612590573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b49190614439565b90508034146125fa5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b602e851461261a5760405162461bcd60e51b81526004016108ca90613fe4565b6001600160a01b0382166000908152610135602052604090205460ff166126775760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108ca565b61013054604051631fff7f2760e11b8152600481018990526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa1580156126c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126e69190614452565b90506001600160a01b038116156127435760008981526101336020908152604080832054905161271d928d92918c918c910161446f565b60405160208183030381529060405280519060200120905061274186868385612fe9565b505b505050505050505050565b6111008161275a6124bd565b6130dd565b6127698282611583565b61102057600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191660011790556127a26124bd565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6127f08282611583565b1561102057600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191690556128276124bd565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6111006124cc565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156128a657610f9183613136565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612900575060408051601f3d908101601f191682019092526128fd91810190614439565b60015b6129635760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108ca565b60008051602061462283398151915281146129d25760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108ca565b50610f918383836131d2565b600054610100900460ff16612a055760405162461bcd60e51b81526004016108ca906144b0565b6114ac6131fd565b600054610100900460ff166114ac5760405162461bcd60e51b81526004016108ca906144b0565b611020828261275f565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61013054604051634a7ab1d560e01b8152600481018890526000916001600160a01b031690634a7ab1d590602401602060405180830381865afa158015612adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aff9190614439565b9050803414612b455760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b60008981526101316020526040808220815161010081019092528054829060ff166004811115612b7757612b77613cbb565b6004811115612b8857612b88613cbb565b81526020016001820154815260200160028201548152602001600382018054612bb090614009565b80601f0160208091040260200160405190810160405280929190818152602001828054612bdc90614009565b8015612c295780601f10612bfe57610100808354040283529160200191612c29565b820191906000526020600020905b815481529060010190602001808311612c0c57829003601f168201915b5050505050815260200160048201548152602001600582015481526020016006820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600782015481525050905061013560008260c001516001600160a01b03166001600160a01b03168152602001908152602001600020600101548160e001518a612cbf91906144fb565b1015612cfe5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b600081516004811115612d1357612d13613cbb565b14612d555760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b8060200151600003612d9d5760405162461bcd60e51b815260206004820152601160248201527014d95c9d9a58d9481b9bdd08195e1a5cdd607a1b60448201526064016108ca565b60008a8152610132602090815260408083208e84529091529020600101548b9003612e035760405162461bcd60e51b81526020600482015260166024820152751c1c9bdc1bdcd85b08185b1c9958591e48195e1a5cdd60521b60448201526064016108ca565b8a816020015103612e605760405162461bcd60e51b815260206004820152602160248201527f63616e27742063726561746520666f7220796f7572206f776e207365727669636044820152606560f81b60648201526084016108ca565b602e8614612e805760405162461bcd60e51b81526004016108ca90613fe4565b61013054604051631fff7f2760e11b8152600481018a90526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612ecb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eef9190614452565b90506001600160a01b03811615612f3f5760008c8c8a8a604051602001612f19949392919061450e565b604051602081830303815290604052805190602001209050612f3d87878385612fe9565b505b8315612fa25761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015612f8957600080fd5b505afa158015612f9d573d6000803e3d6000fd5b505050505b505050505050505050505050565b600060143610801590612fd257503360009081526065602052604090205460ff165b15612fe4575060131936013560601c90565b503390565b6000613042836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905060006130868287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061323492505050565b9050806001600160a01b0316836001600160a01b031614611c385760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064016108ca565b6130e78282611583565b611020576130f481613258565b6130ff83602061326a565b604051602001613110929190614550565b60408051601f198184030181529082905262461bcd60e51b82526108ca916004016145c5565b6001600160a01b0381163b6131a35760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108ca565b60008051602061462283398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6131db8361340d565b6000825111806131e85750805b15610f91576131f7838361344d565b50505050565b600054610100900460ff166132245760405162461bcd60e51b81526004016108ca906144b0565b6114ac61322f6124bd565b612a3e565b60008060006132438585613541565b9150915061325081613583565b509392505050565b606061081d6001600160a01b03831660145b606060006132798360026143d5565b6132849060026144fb565b67ffffffffffffffff81111561329c5761329c613ab9565b6040519080825280601f01601f1916602001820160405280156132c6576020820181803683370190505b509050600360fc1b816000815181106132e1576132e16145d8565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613310576133106145d8565b60200101906001600160f81b031916908160001a90535060006133348460026143d5565b61333f9060016144fb565b90505b60018111156133b7576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613373576133736145d8565b1a60f81b828281518110613389576133896145d8565b60200101906001600160f81b031916908160001a90535060049490941c936133b0816145ee565b9050613342565b5083156134065760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108ca565b9392505050565b61341681613136565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6134b55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108ca565b600080846001600160a01b0316846040516134d09190614605565b600060405180830381855af49150503d806000811461350b576040519150601f19603f3d011682016040523d82523d6000602084013e613510565b606091505b50915091506135388282604051806060016040528060278152602001614642602791396136cd565b95945050505050565b60008082516041036135775760208301516040840151606085015160001a61356b878285856136e6565b94509450505050612073565b50600090506002612073565b600081600481111561359757613597613cbb565b0361359f5750565b60018160048111156135b3576135b3613cbb565b036136005760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108ca565b600281600481111561361457613614613cbb565b036136615760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108ca565b600381600481111561367557613675613cbb565b036111005760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108ca565b606083156136dc575081613406565b61340683836137aa565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561371d57506000905060036137a1565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613771573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661379a576000600192509250506137a1565b9150600090505b94509492505050565b8151156137ba5781518083602001fd5b8060405162461bcd60e51b81526004016108ca91906145c5565b60408051610100810190915280600081526020016000815260200160006001600160a01b0316815260200160008152602001600081526020016060815260200160008152602001600081525090565b6040805161010081019091528060008152602001600081526020016000815260200160608152602001600081526020016000815260200160006001600160a01b03168152602001600081525090565b60006020828403121561388457600080fd5b81356001600160e01b03198116811461340657600080fd5b600080604083850312156138af57600080fd5b50508035926020909101359150565b60008083601f8401126138d057600080fd5b50813567ffffffffffffffff8111156138e857600080fd5b60208301915083602082850101111561207357600080fd5b600080600080600080600060c0888a03121561391b57600080fd5b873596506020880135955060408801359450606088013567ffffffffffffffff81111561394757600080fd5b6139538a828b016138be565b989b979a50959895979660808701359660a0013595509350505050565b60006020828403121561398257600080fd5b5035919050565b6001600160a01b038116811461110057600080fd5b6000602082840312156139b057600080fd5b813561340681613989565b60008060008060008060008060c0898b0312156139d757600080fd5b8835975060208901359650604089013567ffffffffffffffff808211156139fd57600080fd5b613a098c838d016138be565b909850965060608b0135915080821115613a2257600080fd5b50613a2f8b828c016138be565b9095509350506080890135613a4381613989565b8092505060a089013590509295985092959890939650565b60008060408385031215613a6e57600080fd5b823591506020830135613a8081613989565b809150509250929050565b60008060408385031215613a9e57600080fd5b8235613aa981613989565b91506020830135613a8081613989565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215613ae257600080fd5b8235613aed81613989565b9150602083013567ffffffffffffffff80821115613b0a57600080fd5b818501915085601f830112613b1e57600080fd5b813581811115613b3057613b30613ab9565b604051601f8201601f19908116603f01168101908382118183101715613b5857613b58613ab9565b81604052828152886020848701011115613b7157600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b801515811461110057600080fd5b600080600060608486031215613bb657600080fd5b8335613bc181613989565b92506020840135613bd181613b93565b929592945050506040919091013590565b6000806000806000806000806000806101008b8d031215613c0257600080fd5b8a35995060208b0135985060408b0135975060608b0135965060808b013567ffffffffffffffff80821115613c3657600080fd5b613c428e838f016138be565b909850965060a08d0135955060c08d0135915080821115613c6257600080fd5b50613c6f8d828e016138be565b9150809450508092505060e08b013590509295989b9194979a5092959850565b600080600060608486031215613ca457600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052602160045260246000fd5b60028110613ce157613ce1613cbb565b9052565b60005b83811015613d00578181015183820152602001613ce8565b50506000910152565b60008151808452613d21816020860160208601613ce5565b601f01601f19169290920160200192915050565b6000610100613d45848451613cd1565b6020830151602085015260018060a01b036040840151166040850152606083015160608501526080830151608085015260a08301518160a0860152613d8c82860182613d09565b91505060c083015160c085015260e083015160e08501528091505092915050565b6020815260006134066020830184613d35565b60058110613ce157613ce1613cbb565b6000610100613ddf838c613dc0565b896020840152886040840152806060840152613dfd81840189613d09565b6080840197909752505060a08101939093526001600160a01b039190911660c083015260e090910152949350505050565b6000610100613e3d838c613cd1565b89602084015260018060a01b03891660408401528760608401528660808401528060a0840152613e6f81840187613d09565b60c0840195909552505060e001529695505050505050565b6000610100613e97848451613dc0565b60208301516020850152604083015160408501526060830151816060860152613ec282860182613d09565b6080858101519087015260a0808601519087015260c0808601516001600160a01b03169087015260e0948501519490950193909352509192915050565b604081526000613f126040830185613e87565b82810360208401526135388185613d35565b6020815260006134066020830184613e87565b600080600080600060808688031215613f4f57600080fd5b853594506020860135935060408601359250606086013567ffffffffffffffff811115613f7b57600080fd5b613f87888289016138be565b969995985093965092949392505050565b600060208284031215613faa57600080fd5b815161340681613b93565b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b6020808252600b908201526a125b9d985b1a590818da5960aa1b604082015260600190565b600181811c9082168061401d57607f821691505b60208210810361403d57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610f9157600081815260208120601f850160051c8101602086101561406a5750805b601f850160051c820191505b81811015611c3857828155600101614076565b67ffffffffffffffff8311156140a1576140a1613ab9565b6140b5836140af8354614009565b83614043565b6000601f8411600181146140e957600085156140d15750838201355b600019600387901b1c1916600186901b178355614143565b600083815260209020601f19861690835b8281101561411a57868501358255602094850194600190920191016140fa565b50868210156141375760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b87815286602082015260c06040820152600061419360c08301878961414a565b606083019590955250608081019290925260a090910152949350505050565b634e487b7160e01b600052601160045260246000fd5b6000600182016141da576141da6141b2565b5060010190565b87815286602082015285604082015260c06060820152600061420760c08301868861414a565b6001600160a01b039490941660808301525060a0015295945050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b815167ffffffffffffffff8111156142d8576142d8613ab9565b6142ec816142e68454614009565b84614043565b602080601f83116001811461432157600084156143095750858301515b600019600386901b1c1916600185901b178555611c38565b600085815260208120601f198616915b8281101561435057888601518255948401946001909101908401614331565b508582101561436e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006101008b83528a602084015280604084015261439f8184018a8c61414a565b9150506143af6060830188613cd1565b8560808301528460a08301528360c08301528260e08301529a9950505050505050505050565b808202811582820484141761081d5761081d6141b2565b60008261440957634e487b7160e01b600052601260045260246000fd5b500490565b84815260606020820152600061442860608301858761414a565b905082604083015295945050505050565b60006020828403121561444b57600080fd5b5051919050565b60006020828403121561446457600080fd5b815161340681613989565b6c6372656174655365727669636560981b815284600d820152603b60f81b602d82015283602e8201528183604e83013760009101604e019081529392505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8082018082111561081d5761081d6141b2565b6d18dc99585d19541c9bdc1bdcd85b60921b815284600e820152603b60f81b602e82015283602f8201528183604f83013760009101604f019081529392505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614588816017850160208801613ce5565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516145b9816028840160208801613ce5565b01602801949350505050565b6020815260006134066020830184613d09565b634e487b7160e01b600052603260045260246000fd5b6000816145fd576145fd6141b2565b506000190190565b60008251614617818460208701613ce5565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212204101a0ea1f12070439ff1321a6a5682dbe115cfb89975139083fc58ba5f80b4864736f6c63430008110033", + "deployedBytecode": "0x6080604052600436106102305760003560e01c8063715018a61161012e578063c22c4f43116100ab578063ef0e239b1161006f578063ef0e239b1461072e578063f2fde38b1461075b578063f6c53d9b1461077b578063f9eaee0d14610792578063ff420375146107cc57600080fd5b8063c22c4f431461064a578063c2cfee271461067e578063ccaa7d2a146106b2578063d4eee1fc146106e0578063d547741f1461070e57600080fd5b8063a217fddf116100f2578063a217fddf146105b5578063a24bd889146105ca578063a7d5eaea146105dd578063aba21009146105fd578063b5735c1e1461062a57600080fd5b8063715018a6146104f057806371da85f9146105055780637c5a72cd146105575780638da5cb5b1461057757806391d148541461059557600080fd5b80632f2ff15d116101bc578063485cc95511610180578063485cc9551461043b5780634f1ef2861461045b57806352d1902d1461046e578063572b6c05146104835780636ce76f30146104bc57600080fd5b80632f2ff15d1461039b57806336568abe146103bb5780633659cfe6146103db5780633751d89c146103fb5780633ca2ad6f1461041b57600080fd5b8063156b39aa11610203578063156b39aa146102e55780631db087ff1461030a578063248a9ca31461033857806326d00668146103685780632afaf2201461038857600080fd5b806301ffc9a714610235578063089b7c731461026a5780631499f9e61461028c578063154664ed146102c5575b600080fd5b34801561024157600080fd5b50610255610250366004613872565b6107ec565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061028a61028536600461389c565b610823565b005b34801561029857600080fd5b50610130546102ad906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b3480156102d157600080fd5b5061028a6102e0366004613900565b6109c6565b3480156102f157600080fd5b506102fc6101365481565b604051908152602001610261565b34801561031657600080fd5b506102fc610325366004613970565b6101336020526000908152604090205481565b34801561034457600080fd5b506102fc610353366004613970565b600090815260fc602052604090206001015490565b34801561037457600080fd5b5061028a61038336600461399e565b610cde565b6102fc6103963660046139bb565b610d41565b3480156103a757600080fd5b5061028a6103b6366004613a5b565b610f6c565b3480156103c757600080fd5b5061028a6103d6366004613a5b565b610f96565b3480156103e757600080fd5b5061028a6103f636600461399e565b611024565b34801561040757600080fd5b5061028a61041636600461399e565b611103565b34801561042757600080fd5b5061028a610436366004613970565b61115c565b34801561044757600080fd5b5061028a610456366004613a8b565b6111a4565b61028a610469366004613acf565b61131b565b34801561047a57600080fd5b506102fc6113e7565b34801561048f57600080fd5b5061025561049e36600461399e565b6001600160a01b031660009081526065602052604090205460ff1690565b3480156104c857600080fd5b506102fc7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f81565b3480156104fc57600080fd5b5061028a61149a565b34801561051157600080fd5b5061054061052036600461399e565b610135602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610261565b34801561056357600080fd5b5061028a610572366004613ba1565b6114ae565b34801561058357600080fd5b506033546001600160a01b03166102ad565b3480156105a157600080fd5b506102556105b0366004613a5b565b611583565b3480156105c157600080fd5b506102fc600081565b61028a6105d8366004613be2565b6115ae565b3480156105e957600080fd5b5061028a6105f8366004613c8f565b6119dc565b34801561060957600080fd5b5061061d61061836600461389c565b611a5e565b6040516102619190613dad565b34801561063657600080fd5b5061028a61064536600461389c565b611b9b565b34801561065657600080fd5b5061066a610665366004613970565b611c40565b604051610261989796959493929190613dd0565b34801561068a57600080fd5b5061069e61069936600461389c565b611d1d565b604051610261989796959493929190613e2e565b3480156106be57600080fd5b506102fc6106cd366004613970565b6101346020526000908152604090205481565b3480156106ec57600080fd5b506107006106fb36600461389c565b611e04565b604051610261929190613eff565b34801561071a57600080fd5b5061028a610729366004613a5b565b61207a565b34801561073a57600080fd5b5061074e610749366004613970565b61209f565b6040516102619190613f24565b34801561076757600080fd5b5061028a61077636600461399e565b61221f565b34801561078757600080fd5b506102fc61012e5481565b34801561079e57600080fd5b506102556107ad36600461399e565b6001600160a01b03166000908152610135602052604090205460ff1690565b3480156107d857600080fd5b5061028a6107e7366004613f37565b612295565b60006001600160e01b03198216637965db0b60e01b148061081d57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61012f5482906001600160a01b0316632fa117e5826108406124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561088a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ae9190613f98565b6108d35760405162461bcd60e51b81526004016108ca90613fb5565b60405180910390fd5b600082815261013160205260409020600181015484146109255760405162461bcd60e51b815260206004820152600d60248201526c3737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff16600481111561093d5761093d613cbb565b146109825760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b805460ff191660031781556040518381527f853aa4be1ac86f37acfc91d42b57f1fe895205aa6f8f9b7caa77ca257049ab1a9060200160405180910390a150505050565b61012f5487906001600160a01b0316632fa117e5826109e36124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a519190613f98565b610a6d5760405162461bcd60e51b81526004016108ca90613fb5565b60008781526101316020908152604080832061013283528184208c855290925282209091825460ff166004811115610aa757610aa7613cbb565b14610ae95760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b89816001015414610b2c5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b602e8614610b4c5760405162461bcd60e51b81526004016108ca90613fe4565b6001815460ff166001811115610b6457610b64613cbb565b03610ba55760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481d985b1a59185d1959607a1b60448201526064016108ca565b60068201546001600160a01b031660009081526101356020526040902060010154881015610c065760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b8315610c695761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015610c5057600080fd5b505afa158015610c64573d6000803e3d6000fd5b505050505b6003810188905560058101610c7f878983614089565b5060068101859055600781018490556040517ffbfaa6f4e508bec40137ac265a7424e16a2d209355b2f4a35de5a80ba8fec1db90610cca908b908d908b908b908e908c908c90614173565b60405180910390a150505050505050505050565b610ce66124cc565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b61012f5460009089906001600160a01b0316632fa117e582610d616124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610dab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcf9190613f98565b610deb5760405162461bcd60e51b81526004016108ca90613fb5565b610dfa8a8a8a8a8a8a8a612545565b61012e80549081906000610e0d836141c8565b9091555050600081815261013160205260409020805460ff19168155600181018c905560038101610e3f8a8c83614089565b50600581018b90556006810180546001600160a01b0319166001600160a01b0388161790556007810185905560008c81526101336020526040902054158015610e95575060008c81526101346020526040902054155b15610efa5761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015610ee157600080fd5b505af1158015610ef5573d6000803e3d6000fd5b505050505b60008c815261013360205260408120805491610f15836141c8565b91905055507fe7f6435fc92b0ccd6f56395ae67b06f2cdb9680c0179f87f5821431304ad3f3e828d8d8d8d8b8b604051610f5597969594939291906141e1565b60405180910390a1509a9950505050505050505050565b600082815260fc6020526040902060010154610f878161274e565b610f91838361275f565b505050565b610f9e6124bd565b6001600160a01b0316816001600160a01b0316146110165760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108ca565b61102082826127e6565b5050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361106c5760405162461bcd60e51b81526004016108ca90614226565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166110b5600080516020614622833981519152546001600160a01b031690565b6001600160a01b0316146110db5760405162461bcd60e51b81526004016108ca90614272565b6110e48161286b565b6040805160008082526020820190925261110091839190612873565b50565b61110b6124cc565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee69101610d36565b60006111678161274e565b6101368290556040518281527f577d7afcf67637a2f602cba220bbb292c1d715380dd011bfec748c3f641b2fd29060200160405180910390a15050565b600054610100900460ff16158080156111c45750600054600160ff909116105b806111de5750303b1580156111de575060005460ff166001145b6112415760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108ca565b6000805460ff191660011790558015611264576000805461ff0019166101001790555b61126c6129de565b611274612a0d565b61127c612a0d565b61128e60006112896124bd565b612a34565b61012f80546001600160a01b038086166001600160a01b031992831617909255610130805492851692909116919091179055600161012e556112d0601e61115c565b8015610f91576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036113635760405162461bcd60e51b81526004016108ca90614226565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166113ac600080516020614622833981519152546001600160a01b031690565b6001600160a01b0316146113d25760405162461bcd60e51b81526004016108ca90614272565b6113db8261286b565b61102082826001612873565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146114875760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108ca565b5060008051602061462283398151915290565b6114a26124cc565b6114ac6000612a3e565b565b6114b66124cc565b6001600160a01b0383161580156114cb575081155b156115185760405162461bcd60e51b815260206004820152601d60248201527f4f776e65722063616e27742072656d6f7665204f78206164647265737300000060448201526064016108ca565b6001600160a01b03831660008181526101356020908152604091829020805460ff19168615159081178255600190910185905582519384529083015281018290527f42b585a1da1cff4b571e7a78aea1b4601b1d128de41a0feebd8a77aaf48b9d889060600161130e565b600091825260fc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61012f548a906001600160a01b0316632fa117e5826115cb6124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611615573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116399190613f98565b6116555760405162461bcd60e51b81526004016108ca90613fb5565b60008a81526101316020526040808220815161010081019092528054829060ff16600481111561168757611687613cbb565b600481111561169857611698613cbb565b815260200160018201548152602001600282015481526020016003820180546116c090614009565b80601f01602080910402602001604051908101604052809291908181526020018280546116ec90614009565b80156117395780601f1061170e57610100808354040283529160200191611739565b820191906000526020600020905b81548152906001019060200180831161171c57829003601f168201915b5050509183525050600482015460208201526005820154604082015260068201546001600160a01b0316606082015260079091015460809091015290506117878c8c8c8c8c8c8b8b8b612a90565b60408051610100810190915280600081526020018d81526020018260c001516001600160a01b031681526020018b81526020018a815260200189898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020018781526020018481525061013260008d815260200190815260200160002060008e815260200190815260200160002060008201518160000160006101000a81548160ff0219169083600181111561186357611863613cbb565b02179055506020820151600182015560408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a082015160058201906118c090826142be565b5060c0820151600682015560e09091015160079091015560008c81526101336020526040902054158015611901575060008c81526101346020526040902054155b156119665761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b15801561194d57600080fd5b505af1158015611961573d6000803e3d6000fd5b505050505b60008c815261013460205260408120805491611981836141c8565b91905055507fabd26455c3256ad90125661f4c1a4c16fecf585ccade21e749c56d8fd44bb1dd8b8d8a8a60008f8f8d8b6040516119c69998979695949392919061437e565b60405180910390a1505050505050505050505050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611a068161274e565b60008481526101316020908152604080832061013283528184208785529092529091208154600160ff1991821681178455808301546002850155600484018690558254909183911682805b0217905550505050505050565b611a666137d4565b60008381526101326020908152604080832085845290915290819020815161010081019092528054829060ff166001811115611aa457611aa4613cbb565b6001811115611ab557611ab5613cbb565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611afd90614009565b80601f0160208091040260200160405190810160405280929190818152602001828054611b2990614009565b8015611b765780601f10611b4b57610100808354040283529160200191611b76565b820191906000526020600020905b815481529060010190602001808311611b5957829003601f168201915b5050505050815260200160068201548152602001600782015481525050905092915050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611bc58161274e565b6000838152610131602090815260408083206101328352818420600282015485529092528220600381015491929091611bff8660646143d5565b611c0991906143ec565b9050610136548110611c2557825460ff19166002178355611c38565b8254600490849060ff1916600183611a51565b505050505050565b61013160205260009081526040902080546001820154600283015460038401805460ff909416949293919291611c7590614009565b80601f0160208091040260200160405190810160405280929190818152602001828054611ca190614009565b8015611cee5780601f10611cc357610100808354040283529160200191611cee565b820191906000526020600020905b815481529060010190602001808311611cd157829003601f168201915b505050600484015460058501546006860154600790960154949591949093506001600160a01b03909116915088565b61013260209081526000928352604080842090915290825290208054600182015460028301546003840154600485015460058601805460ff9096169694956001600160a01b03909416949293919291611d7590614009565b80601f0160208091040260200160405190810160405280929190818152602001828054611da190614009565b8015611dee5780601f10611dc357610100808354040283529160200191611dee565b820191906000526020600020905b815481529060010190602001808311611dd157829003601f168201915b5050505050908060060154908060070154905088565b611e0c613823565b611e146137d4565b60008481526101316020526040808220815161010081019092528054829060ff166004811115611e4657611e46613cbb565b6004811115611e5757611e57613cbb565b81526020016001820154815260200160028201548152602001600382018054611e7f90614009565b80601f0160208091040260200160405190810160405280929190818152602001828054611eab90614009565b8015611ef85780601f10611ecd57610100808354040283529160200191611ef8565b820191906000526020600020905b815481529060010190602001808311611edb57829003601f168201915b50505091835250506004820154602080830191909152600583015460408084019190915260068401546001600160a01b03166060840152600790930154608090920191909152600088815261013282528281208882529091528181208251610100810190935280549394509092829060ff166001811115611f7b57611f7b613cbb565b6001811115611f8c57611f8c613cbb565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611fd490614009565b80601f016020809104026020016040519081016040528092919081815260200182805461200090614009565b801561204d5780601f106120225761010080835404028352916020019161204d565b820191906000526020600020905b81548152906001019060200180831161203057829003601f168201915b505050918352505060068201546020820152600790910154604090910152919350909150505b9250929050565b600082815260fc60205260409020600101546120958161274e565b610f9183836127e6565b6120a7613823565b61012e5482106120f95760405162461bcd60e51b815260206004820152601a60248201527f54686973207365727669636520646f65736e277420657869737400000000000060448201526064016108ca565b6000828152610131602052604090819020815161010081019092528054829060ff16600481111561212c5761212c613cbb565b600481111561213d5761213d613cbb565b8152602001600182015481526020016002820154815260200160038201805461216590614009565b80601f016020809104026020016040519081016040528092919081815260200182805461219190614009565b80156121de5780601f106121b3576101008083540402835291602001916121de565b820191906000526020600020905b8154815290600101906020018083116121c157829003601f168201915b5050509183525050600482015460208201526005820154604082015260068201546001600160a01b0316606082015260079091015460809091015292915050565b6122276124cc565b6001600160a01b03811661228c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108ca565b61110081612a3e565b61012f5485906001600160a01b0316632fa117e5826122b26124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156122fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123209190613f98565b61233c5760405162461bcd60e51b81526004016108ca90613fb5565b6000858152610131602052604090206001810154871461238e5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff1660048111156123a6576123a6613cbb565b146123eb5760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b602e831461240b5760405162461bcd60e51b81526004016108ca90613fe4565b806007015485101561245f5760405162461bcd60e51b815260206004820152601c60248201527f43616e27742072656475636520726566657272616c20616d6f756e740000000060448201526064016108ca565b6003810161246e848683614089565b50600781018590556040517fae55ce3c351e2400a1a143e7ed66668e581e1656ad1797a317e415d035880916906124ac908890879087908a9061440e565b60405180910390a150505050505050565b60006124c7612fb0565b905090565b6124d46124bd565b6001600160a01b03166124ef6033546001600160a01b031690565b6001600160a01b0316146114ac5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108ca565b61013054604051638a98636360e01b8152600481018890526000916001600160a01b031690638a98636390602401602060405180830381865afa158015612590573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b49190614439565b90508034146125fa5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b602e851461261a5760405162461bcd60e51b81526004016108ca90613fe4565b6001600160a01b0382166000908152610135602052604090205460ff166126775760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108ca565b61013054604051631fff7f2760e11b8152600481018990526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa1580156126c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126e69190614452565b90506001600160a01b038116156127435760008981526101336020908152604080832054905161271d928d92918c918c910161446f565b60405160208183030381529060405280519060200120905061274186868385612fe9565b505b505050505050505050565b6111008161275a6124bd565b6130dd565b6127698282611583565b61102057600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191660011790556127a26124bd565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6127f08282611583565b1561102057600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191690556128276124bd565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6111006124cc565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156128a657610f9183613136565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612900575060408051601f3d908101601f191682019092526128fd91810190614439565b60015b6129635760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108ca565b60008051602061462283398151915281146129d25760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108ca565b50610f918383836131d2565b600054610100900460ff16612a055760405162461bcd60e51b81526004016108ca906144b0565b6114ac6131fd565b600054610100900460ff166114ac5760405162461bcd60e51b81526004016108ca906144b0565b611020828261275f565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61013054604051634a7ab1d560e01b8152600481018890526000916001600160a01b031690634a7ab1d590602401602060405180830381865afa158015612adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aff9190614439565b9050803414612b455760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b60008981526101316020526040808220815161010081019092528054829060ff166004811115612b7757612b77613cbb565b6004811115612b8857612b88613cbb565b81526020016001820154815260200160028201548152602001600382018054612bb090614009565b80601f0160208091040260200160405190810160405280929190818152602001828054612bdc90614009565b8015612c295780601f10612bfe57610100808354040283529160200191612c29565b820191906000526020600020905b815481529060010190602001808311612c0c57829003601f168201915b5050505050815260200160048201548152602001600582015481526020016006820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600782015481525050905061013560008260c001516001600160a01b03166001600160a01b03168152602001908152602001600020600101548160e001518a612cbf91906144fb565b1015612cfe5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b600081516004811115612d1357612d13613cbb565b14612d555760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b8060200151600003612d9d5760405162461bcd60e51b815260206004820152601160248201527014d95c9d9a58d9481b9bdd08195e1a5cdd607a1b60448201526064016108ca565b60008a8152610132602090815260408083208e84529091529020600101548b9003612e035760405162461bcd60e51b81526020600482015260166024820152751c1c9bdc1bdcd85b08185b1c9958591e48195e1a5cdd60521b60448201526064016108ca565b8a816020015103612e605760405162461bcd60e51b815260206004820152602160248201527f63616e27742063726561746520666f7220796f7572206f776e207365727669636044820152606560f81b60648201526084016108ca565b602e8614612e805760405162461bcd60e51b81526004016108ca90613fe4565b61013054604051631fff7f2760e11b8152600481018a90526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612ecb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eef9190614452565b90506001600160a01b03811615612f3f5760008c8c8a8a604051602001612f19949392919061450e565b604051602081830303815290604052805190602001209050612f3d87878385612fe9565b505b8315612fa25761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015612f8957600080fd5b505afa158015612f9d573d6000803e3d6000fd5b505050505b505050505050505050505050565b600060143610801590612fd257503360009081526065602052604090205460ff165b15612fe4575060131936013560601c90565b503390565b6000613042836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905060006130868287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061323492505050565b9050806001600160a01b0316836001600160a01b031614611c385760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064016108ca565b6130e78282611583565b611020576130f481613258565b6130ff83602061326a565b604051602001613110929190614550565b60408051601f198184030181529082905262461bcd60e51b82526108ca916004016145c5565b6001600160a01b0381163b6131a35760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108ca565b60008051602061462283398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6131db8361340d565b6000825111806131e85750805b15610f91576131f7838361344d565b50505050565b600054610100900460ff166132245760405162461bcd60e51b81526004016108ca906144b0565b6114ac61322f6124bd565b612a3e565b60008060006132438585613541565b9150915061325081613583565b509392505050565b606061081d6001600160a01b03831660145b606060006132798360026143d5565b6132849060026144fb565b67ffffffffffffffff81111561329c5761329c613ab9565b6040519080825280601f01601f1916602001820160405280156132c6576020820181803683370190505b509050600360fc1b816000815181106132e1576132e16145d8565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613310576133106145d8565b60200101906001600160f81b031916908160001a90535060006133348460026143d5565b61333f9060016144fb565b90505b60018111156133b7576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613373576133736145d8565b1a60f81b828281518110613389576133896145d8565b60200101906001600160f81b031916908160001a90535060049490941c936133b0816145ee565b9050613342565b5083156134065760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108ca565b9392505050565b61341681613136565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6134b55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108ca565b600080846001600160a01b0316846040516134d09190614605565b600060405180830381855af49150503d806000811461350b576040519150601f19603f3d011682016040523d82523d6000602084013e613510565b606091505b50915091506135388282604051806060016040528060278152602001614642602791396136cd565b95945050505050565b60008082516041036135775760208301516040840151606085015160001a61356b878285856136e6565b94509450505050612073565b50600090506002612073565b600081600481111561359757613597613cbb565b0361359f5750565b60018160048111156135b3576135b3613cbb565b036136005760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108ca565b600281600481111561361457613614613cbb565b036136615760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108ca565b600381600481111561367557613675613cbb565b036111005760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108ca565b606083156136dc575081613406565b61340683836137aa565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561371d57506000905060036137a1565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613771573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661379a576000600192509250506137a1565b9150600090505b94509492505050565b8151156137ba5781518083602001fd5b8060405162461bcd60e51b81526004016108ca91906145c5565b60408051610100810190915280600081526020016000815260200160006001600160a01b0316815260200160008152602001600081526020016060815260200160008152602001600081525090565b6040805161010081019091528060008152602001600081526020016000815260200160608152602001600081526020016000815260200160006001600160a01b03168152602001600081525090565b60006020828403121561388457600080fd5b81356001600160e01b03198116811461340657600080fd5b600080604083850312156138af57600080fd5b50508035926020909101359150565b60008083601f8401126138d057600080fd5b50813567ffffffffffffffff8111156138e857600080fd5b60208301915083602082850101111561207357600080fd5b600080600080600080600060c0888a03121561391b57600080fd5b873596506020880135955060408801359450606088013567ffffffffffffffff81111561394757600080fd5b6139538a828b016138be565b989b979a50959895979660808701359660a0013595509350505050565b60006020828403121561398257600080fd5b5035919050565b6001600160a01b038116811461110057600080fd5b6000602082840312156139b057600080fd5b813561340681613989565b60008060008060008060008060c0898b0312156139d757600080fd5b8835975060208901359650604089013567ffffffffffffffff808211156139fd57600080fd5b613a098c838d016138be565b909850965060608b0135915080821115613a2257600080fd5b50613a2f8b828c016138be565b9095509350506080890135613a4381613989565b8092505060a089013590509295985092959890939650565b60008060408385031215613a6e57600080fd5b823591506020830135613a8081613989565b809150509250929050565b60008060408385031215613a9e57600080fd5b8235613aa981613989565b91506020830135613a8081613989565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215613ae257600080fd5b8235613aed81613989565b9150602083013567ffffffffffffffff80821115613b0a57600080fd5b818501915085601f830112613b1e57600080fd5b813581811115613b3057613b30613ab9565b604051601f8201601f19908116603f01168101908382118183101715613b5857613b58613ab9565b81604052828152886020848701011115613b7157600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b801515811461110057600080fd5b600080600060608486031215613bb657600080fd5b8335613bc181613989565b92506020840135613bd181613b93565b929592945050506040919091013590565b6000806000806000806000806000806101008b8d031215613c0257600080fd5b8a35995060208b0135985060408b0135975060608b0135965060808b013567ffffffffffffffff80821115613c3657600080fd5b613c428e838f016138be565b909850965060a08d0135955060c08d0135915080821115613c6257600080fd5b50613c6f8d828e016138be565b9150809450508092505060e08b013590509295989b9194979a5092959850565b600080600060608486031215613ca457600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052602160045260246000fd5b60028110613ce157613ce1613cbb565b9052565b60005b83811015613d00578181015183820152602001613ce8565b50506000910152565b60008151808452613d21816020860160208601613ce5565b601f01601f19169290920160200192915050565b6000610100613d45848451613cd1565b6020830151602085015260018060a01b036040840151166040850152606083015160608501526080830151608085015260a08301518160a0860152613d8c82860182613d09565b91505060c083015160c085015260e083015160e08501528091505092915050565b6020815260006134066020830184613d35565b60058110613ce157613ce1613cbb565b6000610100613ddf838c613dc0565b896020840152886040840152806060840152613dfd81840189613d09565b6080840197909752505060a08101939093526001600160a01b039190911660c083015260e090910152949350505050565b6000610100613e3d838c613cd1565b89602084015260018060a01b03891660408401528760608401528660808401528060a0840152613e6f81840187613d09565b60c0840195909552505060e001529695505050505050565b6000610100613e97848451613dc0565b60208301516020850152604083015160408501526060830151816060860152613ec282860182613d09565b6080858101519087015260a0808601519087015260c0808601516001600160a01b03169087015260e0948501519490950193909352509192915050565b604081526000613f126040830185613e87565b82810360208401526135388185613d35565b6020815260006134066020830184613e87565b600080600080600060808688031215613f4f57600080fd5b853594506020860135935060408601359250606086013567ffffffffffffffff811115613f7b57600080fd5b613f87888289016138be565b969995985093965092949392505050565b600060208284031215613faa57600080fd5b815161340681613b93565b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b6020808252600b908201526a125b9d985b1a590818da5960aa1b604082015260600190565b600181811c9082168061401d57607f821691505b60208210810361403d57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610f9157600081815260208120601f850160051c8101602086101561406a5750805b601f850160051c820191505b81811015611c3857828155600101614076565b67ffffffffffffffff8311156140a1576140a1613ab9565b6140b5836140af8354614009565b83614043565b6000601f8411600181146140e957600085156140d15750838201355b600019600387901b1c1916600186901b178355614143565b600083815260209020601f19861690835b8281101561411a57868501358255602094850194600190920191016140fa565b50868210156141375760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b87815286602082015260c06040820152600061419360c08301878961414a565b606083019590955250608081019290925260a090910152949350505050565b634e487b7160e01b600052601160045260246000fd5b6000600182016141da576141da6141b2565b5060010190565b87815286602082015285604082015260c06060820152600061420760c08301868861414a565b6001600160a01b039490941660808301525060a0015295945050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b815167ffffffffffffffff8111156142d8576142d8613ab9565b6142ec816142e68454614009565b84614043565b602080601f83116001811461432157600084156143095750858301515b600019600386901b1c1916600185901b178555611c38565b600085815260208120601f198616915b8281101561435057888601518255948401946001909101908401614331565b508582101561436e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006101008b83528a602084015280604084015261439f8184018a8c61414a565b9150506143af6060830188613cd1565b8560808301528460a08301528360c08301528260e08301529a9950505050505050505050565b808202811582820484141761081d5761081d6141b2565b60008261440957634e487b7160e01b600052601260045260246000fd5b500490565b84815260606020820152600061442860608301858761414a565b905082604083015295945050505050565b60006020828403121561444b57600080fd5b5051919050565b60006020828403121561446457600080fd5b815161340681613989565b6c6372656174655365727669636560981b815284600d820152603b60f81b602d82015283602e8201528183604e83013760009101604e019081529392505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8082018082111561081d5761081d6141b2565b6d18dc99585d19541c9bdc1bdcd85b60921b815284600e820152603b60f81b602e82015283602f8201528183604f83013760009101604f019081529392505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614588816017850160208801613ce5565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516145b9816028840160208801613ce5565b01602801949350505050565b6020815260006134066020830184613d09565b634e487b7160e01b600052603260045260246000fd5b6000816145fd576145fd6141b2565b506000190190565b60008251614617818460208701613ce5565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212204101a0ea1f12070439ff1321a6a5682dbe115cfb89975139083fc58ba5f80b4864736f6c63430008110033", "linkReferences": {}, "deployedLinkReferences": {} } From f35e330df0b425935f13c9f4b65ea19e8ce96aa6 Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Sat, 2 Dec 2023 17:01:18 +0000 Subject: [PATCH 33/40] Updated tests & mocks --- packages/client/src/__mocks__/fixtures.ts | 6 ++- packages/client/src/escrow/index.ts | 16 +++---- .../src/proposals/__tests__/proposals.spec.ts | 30 +++++++++--- .../src/services/__tests__/services.spec.ts | 48 ++++++++++++++++--- 4 files changed, 77 insertions(+), 23 deletions(-) diff --git a/packages/client/src/__mocks__/fixtures.ts b/packages/client/src/__mocks__/fixtures.ts index 559f275..0c8d96b 100644 --- a/packages/client/src/__mocks__/fixtures.ts +++ b/packages/client/src/__mocks__/fixtures.ts @@ -4,6 +4,8 @@ import { IProps } from "../services/types"; export const testAddress = "0xRacoon"; export const testName = 'racoon'; export const testUserId = '2371'; +export const testReferrerUserId = '2374'; +export const testReferralAmount = '4664642374'; export const testChainId = 137; export const testUserResponse = { data: { @@ -79,8 +81,8 @@ export const testProposalResponseWithDifferentRateToken = { "data": { "proposal" export const testProtocolAndPlatformResponse = { "data": { "protocols": [{ "protocolEscrowFeeRate": 100 }], "servicePlatform": { "originServiceFeeRate": 0 }, "proposalPlatform": { "originValidatedProposalFeeRate": 0 } } } export const testServiceId = '12'; // rest to 12 before comitting export const testAmount = BigInt('1000'); -export const testServiceResponse = { "data": { "service": { "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ", "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStat": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } } } }; -export const testSearchServicesResponse = { data: { "services": [{ "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ", "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStat": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } }] } } +export const testServiceResponse = { "data": { "service": { "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ", "rateToken": { "id": "0x0000000000000000000000000000000000000000", "address": "0x0000000000000000000000000000000000000000" }, "referralAmount": "0", "referrer": null, "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStat": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } } } }; +export const testSearchServicesResponse = { data: { "services": [{ "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ","rateToken": { "id": "0x0000000000000000000000000000000000000000", "address": "0x0000000000000000000000000000000000000000" }, "referralAmount": "0", "referrer": null, "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStat": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } }] } } export const testServiceDetails = { title: 'test title', about: 'test about', diff --git a/packages/client/src/escrow/index.ts b/packages/client/src/escrow/index.ts index ffc9e3e..ef6e64e 100644 --- a/packages/client/src/escrow/index.ts +++ b/packages/client/src/escrow/index.ts @@ -1,13 +1,13 @@ -import {ERC20, IERC20} from '../blockchain-bindings/erc20'; +import { ERC20, IERC20 } from '../blockchain-bindings/erc20'; import GraphQLClient from '../graphql'; import IPFSClient from '../ipfs'; -import {Proposal} from '../proposals'; -import {Service} from '../services'; -import {ClientTransactionResponse, NetworkEnum, RateToken} from '../types'; -import {calculateApprovalAmount} from '../utils/fees'; -import {ViemClient} from '../viem'; -import {getPaymentsByService, getProtocolAndPlatformsFees} from './graphql/queries'; -import {IEscrow} from "./types"; +import { Proposal } from '../proposals'; +import { Service } from '../services'; +import { ClientTransactionResponse, NetworkEnum, RateToken } from '../types'; +import { calculateApprovalAmount } from '../utils/fees'; +import { ViemClient } from '../viem'; +import { getPaymentsByService, getProtocolAndPlatformsFees } from './graphql/queries'; +import { IEscrow } from "./types"; export class Escrow implements IEscrow { graphQlClient: GraphQLClient; diff --git a/packages/client/src/proposals/__tests__/proposals.spec.ts b/packages/client/src/proposals/__tests__/proposals.spec.ts index 245f813..cb5f565 100644 --- a/packages/client/src/proposals/__tests__/proposals.spec.ts +++ b/packages/client/src/proposals/__tests__/proposals.spec.ts @@ -1,7 +1,22 @@ import { Proposal } from '..'; import { MockGraphQLClient, MockIPFSClient, MockViemClient } from '../../__mocks__/clientMocks'; -import { testAddress, testAmount, testChainId, testCid, testExpirationDate, testIpfsHash, testOwnerAddress, testPlatformDetails, testPlatformId, testPlatformResponse, testPlatformsByOwnerResponse, testProposalDetails, testProposalId, testProposalResponse, testProposalsByServiceId, testProposalsByUser, testProtocolAndPlatformResponse, testServiceId, testSignature, testUserId } from '../../__mocks__/fixtures'; +import { + testAmount, + testExpirationDate, + testIpfsHash, + testPlatformId, + testPlatformResponse, + testProposalDetails, + testProposalId, + testProposalResponse, + testProposalsByServiceId, + testProposalsByUser, + testReferrerUserId, + testServiceId, + testSignature, + testUserId +} from '../../__mocks__/fixtures'; // Additional imports... describe('Platform', () => { @@ -62,19 +77,19 @@ describe('Platform', () => { const proposalDetails = testProposalDetails; const userId = testUserId; const serviceId = testServiceId; - const rateToken = testAddress; const rateAmount = testAmount; const expirationDate = testExpirationDate; + const referrerId = testReferrerUserId; // Act - const resposne = await proposal.update(proposalDetails, userId, serviceId, rateToken, rateAmount.toString(), expirationDate) + const response = await proposal.update(proposalDetails, userId, serviceId, rateAmount.toString(), expirationDate, referrerId) // Assert expect(mockIPFSClient.post).toHaveBeenCalledWith(JSON.stringify(proposalDetails)); expect(mockViemClient.writeContract).toHaveBeenLastCalledWith( 'talentLayerService', 'updateProposal', - [userId, serviceId, rateToken, rateAmount.toString(), testIpfsHash, expirationDate] + [userId, serviceId, rateAmount.toString(), testIpfsHash, expirationDate, referrerId] ) }) }) @@ -85,20 +100,21 @@ describe('Platform', () => { const proposalDetails = testProposalDetails; const userId = testUserId; const serviceId = testServiceId; - const rateToken = testAddress; const rateAmount = testAmount; const expirationDate = testExpirationDate; const signatureResponse = testSignature; + const referrerId = testReferrerUserId; + jest.spyOn(proposal, 'getSignature').mockResolvedValueOnce(signatureResponse); // Act - const resposne = await proposal.create(proposalDetails, userId, serviceId, rateToken, rateAmount.toString(), expirationDate) + const response = await proposal.create(proposalDetails, userId, serviceId, rateAmount.toString(), expirationDate, referrerId) // Assert expect(mockViemClient.writeContract).toHaveBeenCalledWith( 'talentLayerService', 'createProposal', - [userId, serviceId, rateToken, rateAmount.toString(), testPlatformId, testIpfsHash, expirationDate, signatureResponse], + [userId, serviceId, rateAmount.toString(), testPlatformId, testIpfsHash, expirationDate, signatureResponse, referrerId], BigInt(testPlatformResponse.data.platform.proposalPostingFee), ) diff --git a/packages/client/src/services/__tests__/services.spec.ts b/packages/client/src/services/__tests__/services.spec.ts index 08673ce..131add4 100644 --- a/packages/client/src/services/__tests__/services.spec.ts +++ b/packages/client/src/services/__tests__/services.spec.ts @@ -2,7 +2,20 @@ import { Service } from '..'; import { getPlatformById } from '../../platform/graphql/queries'; import { MockGraphQLClient, MockIPFSClient, MockViemClient } from '../../__mocks__/clientMocks'; -import { testAddress, testIpfsHash, testPlatformId, testPlatformResponse, testSearchServiceProps, testSearchServicesResponse, testServiceDetails, testServiceId, testServiceResponse, testSignature, testUserId } from '../../__mocks__/fixtures'; +import { + testAddress, + testIpfsHash, + testPlatformId, + testPlatformResponse, + testReferralAmount, + testSearchServiceProps, + testSearchServicesResponse, + testServiceDetails, + testServiceId, + testServiceResponse, + testSignature, + testUserId +} from '../../__mocks__/fixtures'; describe('Service', () => { let service: Service; @@ -41,7 +54,7 @@ describe('Service', () => { jest.spyOn(service, 'getServiceSignature').mockResolvedValue(testSignature) // Act - const response = await service.create(serviceDetails, userId, platformID); + const response = await service.create(serviceDetails, userId, platformID, testAddress, testReferralAmount); // Assert expect(response.cid).toEqual(testIpfsHash); @@ -50,7 +63,7 @@ describe('Service', () => { expect(mockViemClient.writeContract).toHaveBeenCalledWith( 'talentLayerService', 'createService', - [userId, platformID, testIpfsHash, testSignature], + [userId, platformID, testIpfsHash, testSignature, testAddress, testReferralAmount], BigInt(testPlatformResponse.data.platform.servicePostingFee), ); @@ -58,9 +71,32 @@ describe('Service', () => { }) }) + describe('update', () => { + it('should update a new service', async () => { + // Arrange + const serviceDetails = testServiceDetails; + const userId = testUserId; + const serviceId = 1; + jest.spyOn(service, 'getServiceSignature').mockResolvedValue(testSignature) + + // Act + const response = await service.update(serviceDetails, userId, serviceId,testReferralAmount); + + // Assert + expect(response.cid).toEqual(testIpfsHash); + expect(response.tx).toEqual(testAddress); + expect(mockViemClient.writeContract).toHaveBeenCalledWith( + 'talentLayerService', + 'updateService', + [userId, serviceId, testReferralAmount, testIpfsHash] + ); + + }) + }) + describe('search', () => { - it('should reaturn services based on criteria', async () => { - // Arranage + it('should return services based on criteria', async () => { + // Arrange const props = testSearchServiceProps; // Act @@ -74,7 +110,7 @@ describe('Service', () => { describe('getServices', () => { it('should return services based on criteria', async () => { - // Arranage + // Arrange const props = testSearchServiceProps; // Act From cf436d1ea473ea353d794024a99e38401cae2336 Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Sat, 2 Dec 2023 17:16:33 +0000 Subject: [PATCH 34/40] Added query fields --- packages/client/src/graphql/queries.ts | 10 +++++ packages/client/src/profile/graphql/index.ts | 44 ++++++++++++++++--- .../client/src/proposals/graphql/index.ts | 12 +++++ 3 files changed, 61 insertions(+), 5 deletions(-) diff --git a/packages/client/src/graphql/queries.ts b/packages/client/src/graphql/queries.ts index 8f32b45..e13a403 100644 --- a/packages/client/src/graphql/queries.ts +++ b/packages/client/src/graphql/queries.ts @@ -4,6 +4,11 @@ export const serviceQueryFields = ` createdAt cid referralAmount + referrer { + address + handle + id + } rateToken { address decimals @@ -81,6 +86,11 @@ export const getProposalsByService = (serviceId: string) => ` about video_url } + referrer { + address + handle + id + } status expirationDate } diff --git a/packages/client/src/profile/graphql/index.ts b/packages/client/src/profile/graphql/index.ts index e88ba51..816c323 100644 --- a/packages/client/src/profile/graphql/index.ts +++ b/packages/client/src/profile/graphql/index.ts @@ -10,7 +10,15 @@ export const getProfileByAddress = (address: Hash) => rating delegates userStat { + averageReferredRating + numCreatedProposals + numCreatedServices + numFinishedServicesAsBuyer + numFinishedServicesAsSeller + numGivenReviews numReceivedReviews + numReferredUsers + numReferredUsersReviewsReceived } updatedAt createdAt @@ -44,7 +52,15 @@ export const getProfiles = (numberPerPage?: number, offset?: number, searchQuery address handle userStat { + averageReferredRating + numCreatedProposals + numCreatedServices + numFinishedServicesAsBuyer + numFinishedServicesAsSeller + numGivenReviews numReceivedReviews + numReferredUsers + numReferredUsersReviewsReceived } rating } @@ -61,7 +77,15 @@ export const getProfileById = (id: string) => ` rating delegates userStat { - numReceivedReviews + averageReferredRating + numCreatedProposals + numCreatedServices + numFinishedServicesAsBuyer + numFinishedServicesAsSeller + numGivenReviews + numReceivedReviews + numReferredUsers + numReferredUsersReviewsReceived } updatedAt createdAt @@ -95,16 +119,26 @@ export const getUserTotalGains = (id: string) => ` { user(id: "${id}") { totalGains{ - id - totalGain - token { + id + totalGain + token { id name symbol decimals - } + } } + referralGains { + availableBalance + totalGain + token { + address + decimals + symbol + name + } } + } } `; diff --git a/packages/client/src/proposals/graphql/index.ts b/packages/client/src/proposals/graphql/index.ts index a7db950..fcfde83 100644 --- a/packages/client/src/proposals/graphql/index.ts +++ b/packages/client/src/proposals/graphql/index.ts @@ -12,6 +12,10 @@ export const getProposalById = (id: string) => ` numReceivedReviews } } + referrer { + address + handle + } platform { id } @@ -71,6 +75,10 @@ export const getAllProposalsByServiceId = (id: string) => ` numReceivedReviews } } + referrer { + address + handle + } description { id about @@ -113,6 +121,10 @@ export const getAllProposalsByUser = (id: string) => ` handle } } + referrer { + address + handle + } description { id about From 637cad5c7b0c13efa9b4d300eb1f326e6d5d1788 Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Sat, 2 Dec 2023 17:18:25 +0000 Subject: [PATCH 35/40] Refactor --- packages/client/src/utils/fees.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/utils/fees.ts b/packages/client/src/utils/fees.ts index 5ee776d..95f3430 100644 --- a/packages/client/src/utils/fees.ts +++ b/packages/client/src/utils/fees.ts @@ -1,4 +1,4 @@ -import {FEE_RATE_DIVIDER} from '../constants'; +import { FEE_RATE_DIVIDER } from '../constants'; export const calculateApprovalAmount = ( proposalRateAmount: string, From 4efcc92b33cc0c34d5f4fc53d31042eb701771c9 Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Fri, 8 Dec 2023 10:44:53 +0000 Subject: [PATCH 36/40] Merge chain config --- packages/client/src/escrow/index.ts | 4 +--- packages/client/src/index.ts | 2 +- packages/client/src/services/index.ts | 12 ------------ 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/packages/client/src/escrow/index.ts b/packages/client/src/escrow/index.ts index 2e9daaa..978d4eb 100644 --- a/packages/client/src/escrow/index.ts +++ b/packages/client/src/escrow/index.ts @@ -3,14 +3,12 @@ import GraphQLClient from '../graphql'; import IPFSClient from '../ipfs'; import { Proposal } from '../proposals'; import { Service } from '../services'; -import { ChainConfig, ClientTransactionResponse, NetworkEnum, RateToken } from '../types'; +import { ChainConfig, ClientTransactionResponse, RateToken } from '../types'; import { calculateApprovalAmount } from '../utils/fees'; import { ViemClient } from '../viem'; import { getPaymentsByService, getProtocolAndPlatformsFees } from './graphql/queries'; import { IEscrow } from "./types"; - - /** * Release and reimburse payments using TalentLayer escrow * diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index f76a532..269f1b8 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -18,7 +18,7 @@ import { Service } from './services'; import { IReview } from './reviews/types'; import { Review } from './reviews'; import { IService } from "./services/types"; -import { isCustomChainConfig, isNetworkEnum } from './utils/typeguard'; +import { isNetworkEnum } from './utils/typeguard'; /** * Main client for interacting with the TalentLayer protocol. diff --git a/packages/client/src/services/index.ts b/packages/client/src/services/index.ts index cefe71b..b4c6665 100644 --- a/packages/client/src/services/index.ts +++ b/packages/client/src/services/index.ts @@ -16,18 +16,6 @@ import { ServiceDetails, } from './types'; -export interface IService { - getOne(id: string): Promise; - create( - serviceDetails: ServiceDetails, - userId: string, - platformId: number, - ): Promise; - updloadServiceDataToIpfs(serviceData: ServiceDetails): Promise; - getServices(params: IProps): Promise; - search(params: IProps): Promise; -} - /** * Class representing Services inside TalentLayer */ From df8a232eec6d5cf8b8fef91b8c6e700ca15487f9 Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Fri, 8 Dec 2023 10:46:12 +0000 Subject: [PATCH 37/40] Added missing natspec --- packages/client/src/services/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/client/src/services/index.ts b/packages/client/src/services/index.ts index b4c6665..d68a30a 100644 --- a/packages/client/src/services/index.ts +++ b/packages/client/src/services/index.ts @@ -106,6 +106,8 @@ export class Service implements IService { * @param {ServiceDetails} serviceDetails - The details of the service to create. * @param {string} userId - The user ID creating the service. * @param {number} platformId - The platform ID where the service is created. + * @param {string} token - The address of the token used for this service. + * @param {string} referralAmount - The user ID of the referrer (default 0 if no referrer). * @returns {Promise} - A promise that resolves to the transaction response of the service creation. */ public async create( From cc1a24cc71b9d94d05a0c9b80847815401c9f6f9 Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Fri, 8 Dec 2023 13:40:12 +0000 Subject: [PATCH 38/40] Corrected typo --- packages/client/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index 269f1b8..0a00c91 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -56,7 +56,7 @@ export class TalentLayerClient { // if user has given custom chain config, that will take priority this.chainConfig = config.customChainConfig } else { - throw Error('Atleast one of chainId or customChainConfig need to be provided') + throw Error('At least one of chainId or customChainConfig need to be provided') } if (isNetworkEnum(this.chainConfig.networkId)) { From 293c374cc48b75e599f9aef03b78c4bd8021f7b2 Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Fri, 8 Dec 2023 14:30:33 +0000 Subject: [PATCH 39/40] Corrected typo --- packages/client/src/__tests__/talentLayerClient.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/__tests__/talentLayerClient.spec.ts b/packages/client/src/__tests__/talentLayerClient.spec.ts index 3f09cff..e1a5c0c 100644 --- a/packages/client/src/__tests__/talentLayerClient.spec.ts +++ b/packages/client/src/__tests__/talentLayerClient.spec.ts @@ -158,7 +158,7 @@ describe('TalentLayerClient:customchainConfig', () => { platformId: testPlatformId, signatureApiUrl: signatureApiUrl }) - }).toThrow('Atleast one of chainId or customChainConfig need to be provided') + }).toThrow('At least one of chainId or customChainConfig need to be provided') }) From 67941dc3bc50ec547e7bade95f04ae15901a49ff Mon Sep 17 00:00:00 2001 From: "Quentin D.C" Date: Tue, 27 Feb 2024 09:57:11 +0400 Subject: [PATCH 40/40] Added Loggers (to be removed) --- package-lock.json | 2 +- packages/client/src/index.ts | 2 +- packages/client/src/viem/index.ts | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ba88001..dda5f16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15188,7 +15188,7 @@ "axios": "^1.5.0", "ipfs-http-client": "59.0.0", "tsup": "7.2.0", - "viem": "^1.10.14" + "viem": "^1.10.9" }, "devDependencies": { "@turbo/gen": "^1.10.12", diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index 0a00c91..2cfbcb0 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -39,7 +39,7 @@ export class TalentLayerClient { /** @hidden */ constructor(config: TalentLayerClientConfig) { - console.log('SDK: client initialising', config); + console.log('SDK: client initialising with special Racoon versionzzzz', config); this.platformID = config.platformId; this.ipfsClient = new IPFSClient({ diff --git a/packages/client/src/viem/index.ts b/packages/client/src/viem/index.ts index 6647643..0dab1b3 100644 --- a/packages/client/src/viem/index.ts +++ b/packages/client/src/viem/index.ts @@ -96,13 +96,16 @@ export class ViemClient { ): Promise { // @ts-ignore const [address] = await this.client.getAddresses(); - + console.log('racoon address', address) if (!address) { throw Error('Wallet Client not initialised properly'); } const chainConfig = this.chainConfig; const contract = chainConfig.contracts[contractName]; + console.log('racoon contract', contract) + console.log('racoon this.client.getAddresses()', address) + console.log('racoon args', args) if (!contract) { throw Error(`Invalid contract name passed. ${contractName}`);