diff --git a/packages/server/tests/acceptance/htsPrecompile.spec.ts b/packages/server/tests/acceptance/htsPrecompile.spec.ts index a050d8c460..48487973d7 100644 --- a/packages/server/tests/acceptance/htsPrecompile.spec.ts +++ b/packages/server/tests/acceptance/htsPrecompile.spec.ts @@ -54,7 +54,7 @@ describe('@htsprecompile Acceptance Tests', async function () { let HTSTokenWithCustomFeesContractAddress; this.beforeAll(async () => { - accounts[0] = await servicesNode.createAliasAccount(170, relay.provider); + accounts[0] = await servicesNode.createAliasAccount(200, relay.provider); accounts[1] = await servicesNode.createAliasAccount(30, relay.provider); accounts[2] = await servicesNode.createAliasAccount(30, relay.provider); @@ -704,7 +704,7 @@ describe('@htsprecompile Acceptance Tests', async function () { describe('CryptoTransfer Tests', async function() { let NftSerialNumber; let NftSerialNumber2; - + async function setKyc(tokenAddress) { const grantKycTx = await baseHTSContractOwner.grantTokenKycPublic(tokenAddress, accounts[1].wallet.address, { gasLimit: 1_000_000 }); expect((await grantKycTx.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode).to.equal(TX_SUCCESS_CODE); @@ -748,7 +748,7 @@ describe('@htsprecompile Acceptance Tests', async function () { NftSerialNumber2 = serialNumbers[1]; await setKyc(NftHTSTokenContractAddress); - + // setup the transfer const tokenTransferList = [{ token: `${NftHTSTokenContractAddress}`, @@ -774,7 +774,7 @@ describe('@htsprecompile Acceptance Tests', async function () { expect((await txMint.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode).to.be.equal(TX_SUCCESS_CODE); const { serialNumbers } = (await txMint.wait()).events.filter(e => e.event === 'MintedToken')[0].args; const NftSerialNumber = serialNumbers[0]; - + // setup the transfer const tokenTransferList = [{ token: `${NftHTSTokenContractAddress}`, @@ -843,7 +843,7 @@ describe('@htsprecompile Acceptance Tests', async function () { } }); - it('should fail to swap approved non-fungible tokens', async function() { + it('should fail to swap approved non-fungible tokens', async function() { const txApprove1 = await baseHTSContract.setApprovalForAllPublic(NftHTSTokenContractAddress, accounts[1].wallet.address, true, { gasLimit: 1_000_000 }); expect((await txApprove1.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode).to.equal(TX_SUCCESS_CODE); @@ -867,14 +867,14 @@ describe('@htsprecompile Acceptance Tests', async function () { try{ const txXfer = await baseHTSContract.cryptoTransferPublic(tokenTransferList); - expect((await txXfer.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode).to.equal(TX_SUCCESS_CODE); + expect((await txXfer.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode).to.equal(TX_SUCCESS_CODE); } catch (error: any) { expect(error.code).to.equal("CALL_EXCEPTION"); expect(error.reason).to.equal("transaction failed"); } }); - it('should fail to transfer fungible and non-fungible tokens in a single tokenTransferList', async function() { + it('should fail to transfer fungible and non-fungible tokens in a single tokenTransferList', async function() { // setup the transfer const xferAmount = 10; const tokenTransferList = [{ @@ -897,11 +897,64 @@ describe('@htsprecompile Acceptance Tests', async function () { }]; try { const txXfer = await baseHTSContract.cryptoTransferPublic(tokenTransferList); - const response = (await txXfer.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode; + const response = (await txXfer.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode; } catch (error: any) { expect(error.code).to.equal("CALL_EXCEPTION"); expect(error.reason).to.equal("transaction failed"); } }); }); + + describe('HTS Precompile for token check methods', async function() { + it('should return false for isToken with passed contract address', async function() { + const tx = await baseHTSContract.isTokenPublic(BaseHTSContractAddress, { gasLimit: 1000000 }); + const txReceipt = await tx.wait(); + + const responseCode = txReceipt.events.filter(e => e.event === 'ResponseCode')[0].args.responseCode; + expect(responseCode).to.equal(TX_SUCCESS_CODE); + + const isTokenFlag = txReceipt.events.filter(e => e.event === 'IsToken')[0].args.isToken; + expect(isTokenFlag).to.equal(false); + }); + it('should return true for isToken with passed token address', async function() { + const tx = await baseHTSContract.isTokenPublic(HTSTokenContractAddress, { gasLimit: 1000000 }); + const txReceipt = await tx.wait(); + + const responseCode = txReceipt.events.filter(e => e.event === 'ResponseCode')[0].args.responseCode; + expect(responseCode).to.equal(TX_SUCCESS_CODE); + + const isTokenFlag = txReceipt.events.filter(e => e.event === 'IsToken')[0].args.isToken; + expect(isTokenFlag).to.equal(true); + }); + it('should return 0 for getTokenType with passed FUNGIBLE_COMMON token', async function() { + const tx = await baseHTSContract.getTokenTypePublic(HTSTokenContractAddress, { gasLimit: 1000000 }); + const txReceipt = await tx.wait(); + + const responseCode = txReceipt.events.filter(e => e.event === 'ResponseCode')[0].args.responseCode; + expect(responseCode).to.equal(TX_SUCCESS_CODE); + + const tokenType = txReceipt.events.filter(e => e.event === 'TokenType')[0].args.tokenType; + expect(tokenType).to.equal(0); + }); + it('should return 1 for getTokenType with passed HTS NON_FUNGIBLE_UNIQUE token', async function() { + const tx = await baseHTSContract.getTokenTypePublic(NftHTSTokenContractAddress, { gasLimit: 1000000 }); + const txReceipt = await tx.wait(); + + const responseCode = txReceipt.events.filter(e => e.event === 'ResponseCode')[0].args.responseCode; + expect(responseCode).to.equal(TX_SUCCESS_CODE); + + const tokenType = txReceipt.events.filter(e => e.event === 'TokenType')[0].args.tokenType; + expect(tokenType).to.equal(1); + }); + it('should throw an exception for getTokenType with passed contract address', async function() { + let hasError = false; + try { + const tx = await baseHTSContract.getTokenTypePublic(BaseHTSContractAddress, { gasLimit: 1000000 }); + await tx.wait(); + } catch (e) { + hasError = true; + } + expect(hasError).to.equal(true); + }); + }); }); diff --git a/packages/server/tests/contracts/BaseHTS.json b/packages/server/tests/contracts/BaseHTS.json index 711d943282..bcad1038fa 100644 --- a/packages/server/tests/contracts/BaseHTS.json +++ b/packages/server/tests/contracts/BaseHTS.json @@ -116,9 +116,9 @@ "type": "bool" }, { - "internalType": "int64", + "internalType": "uint32", "name": "maxSupply", - "type": "int64" + "type": "uint32" }, { "internalType": "bool", @@ -347,6 +347,19 @@ "name": "FungibleTokenInfo", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "isToken", + "type": "bool" + } + ], + "name": "IsToken", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -414,9 +427,9 @@ "type": "bool" }, { - "internalType": "int64", + "internalType": "uint32", "name": "maxSupply", - "type": "int64" + "type": "uint32" }, { "internalType": "bool", @@ -896,9 +909,9 @@ "type": "bool" }, { - "internalType": "int64", + "internalType": "uint32", "name": "maxSupply", - "type": "int64" + "type": "uint32" }, { "internalType": "bool", @@ -1117,6 +1130,19 @@ "name": "TokenInfo", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "int32", + "name": "tokenType", + "type": "int32" + } + ], + "name": "TokenType", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -1474,9 +1500,9 @@ "type": "bool" }, { - "internalType": "int64", + "internalType": "uint32", "name": "maxSupply", - "type": "int64" + "type": "uint32" }, { "internalType": "bool", @@ -1756,9 +1782,9 @@ "type": "bool" }, { - "internalType": "int64", + "internalType": "uint32", "name": "maxSupply", - "type": "int64" + "type": "uint32" }, { "internalType": "bool", @@ -2306,9 +2332,9 @@ "type": "bool" }, { - "internalType": "int64", + "internalType": "uint32", "name": "maxSupply", - "type": "int64" + "type": "uint32" }, { "internalType": "bool", @@ -2526,6 +2552,30 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getTokenTypePublic", + "outputs": [ + { + "internalType": "int64", + "name": "responseCode", + "type": "int64" + }, + { + "internalType": "int32", + "name": "tokenType", + "type": "int32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -2695,6 +2745,30 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "isTokenPublic", + "outputs": [ + { + "internalType": "int64", + "name": "responseCode", + "type": "int64" + }, + { + "internalType": "bool", + "name": "isTokenFlag", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -3133,8 +3207,8 @@ "type": "function" } ], - "bytecode": "0x60c06040526009608081905268746f6b656e4e616d6560b81b60a09081526200002c9160019190620000c7565b5060408051808201909152600b8082526a1d1bdad95b94de5b589bdb60aa1b60209092019182526200006191600291620000c7565b50604080518082019091526004808252636d656d6f60e01b60209092019182526200008f91600391620000c7565b50600480546001600160a81b031916700800000000000003e800000000000003e8179055348015620000c057600080fd5b50620001aa565b828054620000d5906200016d565b90600052602060002090601f016020900481019282620000f9576000855562000144565b82601f106200011457805160ff191683800117855562000144565b8280016001018555821562000144579182015b828111156200014457825182559160200191906001019062000127565b506200015292915062000156565b5090565b5b8082111562000152576000815560010162000157565b600181811c908216806200018257607f821691505b60208210811415620001a457634e487b7160e01b600052602260045260246000fd5b50919050565b615b9b80620001ba6000396000f3fe6080604052600436106102c65760003560e01c80638070905f11610179578063d85f74c1116100d6578063f2f38a741161008a578063f848fec411610064578063f848fec414610844578063f9e978bd14610864578063fdc8321e1461088457600080fd5b8063f2f38a74146107d6578063f4a01e5b14610804578063f7be34251461082457600080fd5b8063eee55ac8116100bb578063eee55ac814610776578063f25b120014610796578063f2c31ff4146107b657600080fd5b8063d85f74c114610743578063d92ac2481461075657600080fd5b8063a345f7bd1161012d578063af99c63311610112578063af99c633146106d5578063c0b19b6d146106f5578063d614cdb81461072357600080fd5b8063a345f7bd1461067b578063a3ad5b551461069b57600080fd5b80638ba74da01161015e5780638ba74da0146106285780638f8d7f991461063b5780639604ca651461065b57600080fd5b80638070905f146105d957806386f88d881461060857600080fd5b80634cbdb37b1161022757806369837dc2116101db5780636da6b1f0116101c05780636da6b1f0146105795780637c41ad2c146105995780637d3e5da8146105b957600080fd5b806369837dc21461052b5780636a4dde211461055957600080fd5b8063593d6e821161020c578063593d6e82146104a65780635a5e6c31146104c65780635b9076b7146104fb57600080fd5b80634cbdb37b1461045857806356af84031461048657600080fd5b80632eecbca31161027e5780633eed2c39116102635780633eed2c39146104035780634b5c6687146104235780634ba670351461043857600080fd5b80632eecbca3146103c35780633b3bff0f146103e357600080fd5b806319db44b6116102af57806319db44b6146103385780632b256ec8146103755780632d73bb2e146103a357600080fd5b80630fd2601e146102cb57806313c05dd814610303575b600080fd5b3480156102d757600080fd5b506102eb6102e6366004613c51565b6108a4565b60405160079190910b81526020015b60405180910390f35b34801561030f57600080fd5b5061032361031e366004613c8a565b610968565b604080519283529015156020830152016102fa565b34801561034457600080fd5b50610358610353366004613cd5565b6109e6565b604080519283526001600160a01b039091166020830152016102fa565b34801561038157600080fd5b50610395610390366004613d01565b610a6a565b6040519081526020016102fa565b3480156103af57600080fd5b506103956103be366004613c51565b610b56565b3480156103cf57600080fd5b506102eb6103de366004613c51565b610b9b565b3480156103ef57600080fd5b506103956103fe366004613d01565b610bd2565b34801561040f57600080fd5b5061032361041e366004613d01565b610cac565b610436610431366004613d01565b610d26565b005b34801561044457600080fd5b50610395610453366004613d2d565b611114565b34801561046457600080fd5b50610478610473366004613d89565b611160565b6040516102fa9291906142ac565b34801561049257600080fd5b506103956104a13660046143e6565b6111d6565b3480156104b257600080fd5b506103956104c13660046144be565b611220565b3480156104d257600080fd5b506104e66104e1366004613c8a565b6112fd565b604080519283526020830191909152016102fa565b34801561050757600080fd5b5061051b610516366004613d01565b61136e565b6040516102fa949392919061453b565b34801561053757600080fd5b5061054b610546366004613d01565b611400565b6040516102fa9291906145b7565b34801561056557600080fd5b50610323610574366004613c51565b611475565b34801561058557600080fd5b50610395610594366004613d2d565b6114ec565b3480156105a557600080fd5b506103956105b4366004613d01565b6114fa565b3480156105c557600080fd5b506103956105d4366004613c51565b611528565b3480156105e557600080fd5b506105f96105f436600461460e565b611534565b6040516102fa93929190614757565b34801561061457600080fd5b50610323610623366004613d01565b6115bc565b610436610636366004613c51565b61162d565b34801561064757600080fd5b506102eb610656366004613c51565b611aef565b34801561066757600080fd5b50610395610676366004614789565b611b25565b34801561068757600080fd5b50610395610696366004613d01565b611b5a565b3480156106a757600080fd5b506106bb6106b6366004613c51565b611ba0565b6040805160079390930b83529015156020830152016102fa565b3480156106e157600080fd5b506102eb6106f0366004613c51565b611c92565b34801561070157600080fd5b50610715610710366004613d01565b611cc8565b6040516102fa9291906147fe565b34801561072f57600080fd5b5061071561073e366004613d01565b611dbf565b610436610751366004613d01565b611ec9565b34801561076257600080fd5b50610395610771366004614838565b61226e565b34801561078257600080fd5b506103956107913660046144be565b61227b565b3480156107a257600080fd5b506103956107b1366004614886565b61230e565b3480156107c257600080fd5b506106bb6107d1366004613c51565b61231b565b3480156107e257600080fd5b506107f66107f1366004613d01565b6123f6565b6040516102fa9291906148c6565b34801561081057600080fd5b5061039561081f366004613c51565b61246b565b34801561083057600080fd5b5061039561083f366004613d01565b612477565b34801561085057600080fd5b5061039561085f3660046148df565b61255a565b34801561087057600080fd5b5061043661087f366004614920565b612567565b34801561089057600080fd5b5061039561089f36600461493d565b6125dd565b604051638f8d7f9960e01b81526001600160a01b038084166004830152821660248201526000903090638f8d7f99906044015b602060405180830381600087803b1580156108f157600080fd5b505af1158015610905573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109299190614988565b604051600782900b8152909150600080516020615b468339815191529060200160405180910390a1600781900b60161461096257600080fd5b92915050565b6000806109768585856127b4565b6040518281529193509150600080516020615b468339815191529060200160405180910390a1601682146109a957600080fd5b60405181151581527e1c2e72360171244b3bb8cc8ddd767820edf37138ad6f129fb3574b407c307d906020015b60405180910390a1935093915050565b6000806109f384846128b3565b6040518281529193509150600080516020615b468339815191529060200160405180910390a160168214610a2657600080fd5b6040516001600160a01b03821681527fc2c78c7c31baf14949e75c51df12be56edb9af523cf82839c2869bbcf13b3ecb906020015b60405180910390a19250929050565b604051631f106b4b60e21b81526001600160a01b03821660048201526000903090637c41ad2c90602401602060405180830381600087803b158015610aae57600080fd5b505af1158015610ac2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae691906149a5565b9050600080516020615b4683398151915281604051610b0791815260200190565b60405180910390a160168114610b1c57600080fd5b604051600181527f0c9c765845f4d139956bb8fc8decb2eec6093c9c608b809641b16054b29f0e13906020015b60405180910390a1919050565b6000610b628383612993565b60070b9050600080516020615b4683398151915281604051610b8691815260200190565b60405180910390a16016811461096257600080fd5b60405163af99c63360e01b81526001600160a01b03808416600483015282166024820152600090309063af99c633906044016108d7565b6040516001600160a01b03821660248201526000908190819061016790633b3bff0f60e01b906044015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610c3a91906149be565b6000604051808303816000865af19150503d8060008114610c77576040519150601f19603f3d011682016040523d82523d6000602084013e610c7c565b606091505b509150915081610c8d576015610ca1565b80806020019051810190610ca191906149ec565b60030b949350505050565b600080610cb8836129e2565b6040518281529193509150600080516020615b468339815191529060200160405180910390a160168214610ceb57600080fd5b60405181151581527f6b7f3306751292f85ab4161ee2b0ac16dfc8ded13e6446ce6bd859d0a2f4c78e906020015b60405180910390a1915091565b60408051600480825260a08201909252600091816020015b610d46613ac3565b815260200190600190039081610d3e579050509050610d7960006006600160405180602001604052806000815250612adf565b81600081518110610d8c57610d8c614a07565b6020026020010181905250610db260018060405180602001604052806000815250612b16565b81600181518110610dc557610dc5614a07565b6020026020010181905250610dec6002600160405180602001604052806000815250612b16565b81600281518110610dff57610dff614a07565b6020026020010181905250610e266003600160405180602001604052806000815250612b16565b81600381518110610e3957610e39614a07565b602002602001018190525060006040518060600160405280600063ffffffff168152602001846001600160a01b03168152602001627a120063ffffffff168152509050600060405180610120016040528060018054610e9790614a1d565b80601f0160208091040260200160405190810160405280929190818152602001828054610ec390614a1d565b8015610f105780601f10610ee557610100808354040283529160200191610f10565b820191906000526020600020905b815481529060010190602001808311610ef357829003601f168201915b5050505050815260200160028054610f2790614a1d565b80601f0160208091040260200160405190810160405280929190818152602001828054610f5390614a1d565b8015610fa05780601f10610f7557610100808354040283529160200191610fa0565b820191906000526020600020905b815481529060010190602001808311610f8357829003601f168201915b50505050508152602001856001600160a01b0316815260200160038054610fc690614a1d565b80601f0160208091040260200160405190810160405280929190818152602001828054610ff290614a1d565b801561103f5780601f106110145761010080835404028352916020019161103f565b820191906000526020600020905b81548152906001019060200180831161102257829003601f168201915b50505091835250506001602082015260045468010000000000000000810460070b6040830152600160a01b810460ff16151560608301526080820186905260a090910184905290915060009081906110be90849067ffffffffffffffff811690700100000000000000000000000000000000900463ffffffff16612b4b565b9092509050601682146110d057600080fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050565b600061112285858585612c79565b9050600080516020615b468339815191528160405161114391815260200190565b60405180910390a16016811461115857600080fd5b949350505050565b600061116a613b20565b6111748484612d89565b6040518281529193509150600080516020615b468339815191529060200160405180910390a1601682146111a757600080fd5b7fd010ef68d3ac3e07c14bed496400730a484fd17c48a4d373cbc4722a56540def81604051610a5b9190614a58565b60006111e3848484612e7c565b9050600080516020615b468339815191528160405161120491815260200190565b60405180910390a16016811461121957600080fd5b9392505050565b60008060006101676001600160a01b031663593d6e8260e01b868660405160240161124c929190614a6b565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161128a91906149be565b6000604051808303816000865af19150503d80600081146112c7576040519150601f19603f3d011682016040523d82523d6000602084013e6112cc565b606091505b5091509150816112dd5760156112f1565b808060200190518101906112f191906149ec565b60030b95945050505050565b60008061130b858585612f5c565b6040518281529193509150600080516020615b468339815191529060200160405180910390a16016821461133e57600080fd5b6040518181527f25b6684a7e8fe1b676e9c39c8dd65034fbafea906d3bdfd97bf748b7b55e14c8906020016109d6565b6000606080606061137e85613048565b604051600785900b815293975091955093509150600080516020615b468339815191529060200160405180910390a1600784900b6016146113be57600080fd5b7f2efc8334b040613a552197fe34283d6ca2909c8ffae393e128424931f20c69b38383836040516113f193929190614aae565b60405180910390a19193509193565b600061140a613b5b565b61141383613148565b6040518281529193509150600080516020615b468339815191529060200160405180910390a16016821461144657600080fd5b7fea9419ffbaa766adf982c4c9864330eee1d848eff36c79e510e7e589c8bb265f81604051610d199190614ae7565b6000806114828484613231565b60405160079290920b80835293509150600080516020615b468339815191529060200160405180910390a1601682146114ba57600080fd5b60405181151581527f59800d968fcce138300a0019410b4b75041610d65b3cdc5f31656b03ed14912e90602001610a5b565b600061112285858585613282565b6040516001600160a01b03821660248201526000908190819061016790631f106b4b60e21b90604401610bfc565b6000610b6283836132e3565b6000806060611544868686613332565b6040518381529295509093509150600080516020615b468339815191529060200160405180910390a16016831461157a57600080fd5b7feff23992f47b3c101679f8b4dc9d3e242c903909dba4a453f2b2341ad463b0e282826040516115ab929190614afa565b60405180910390a193509350939050565b6000806115c883613430565b6040518281529193509150600080516020615b468339815191529060200160405180910390a1601682146115fb57600080fd5b60405181151581527f9ee19e13dfa1ba8db2502e15ff56dbecdeb0e0473323fb195473ce648030a2cd90602001610d19565b604080516001808252818301909252600091816020015b61164c613ac3565b81526020019060019003908161164457905050905061167e600080600160405180602001604052806000815250612adf565b8160008151811061169157611691614a07565b602002602001018190525060006040518060600160405280600063ffffffff168152602001856001600160a01b03168152602001627a120063ffffffff1681525090506000604051806101200160405280600180546116ef90614a1d565b80601f016020809104026020016040519081016040528092919081815260200182805461171b90614a1d565b80156117685780601f1061173d57610100808354040283529160200191611768565b820191906000526020600020905b81548152906001019060200180831161174b57829003601f168201915b505050505081526020016002805461177f90614a1d565b80601f01602080910402602001604051908101604052809291908181526020018280546117ab90614a1d565b80156117f85780601f106117cd576101008083540402835291602001916117f8565b820191906000526020600020905b8154815290600101906020018083116117db57829003601f168201915b50505050508152602001866001600160a01b031681526020016003805461181e90614a1d565b80601f016020809104026020016040519081016040528092919081815260200182805461184a90614a1d565b80156118975780601f1061186c57610100808354040283529160200191611897565b820191906000526020600020905b81548152906001019060200180831161187a57829003601f168201915b505050918352505060016020820181905260045468010000000000000000900460070b6040808401919091526000606084018190526080840188905260a09093018690528051828152808201909152929350909190816020015b6040805160a0810182526000808252602080830182905292820181905260608201819052608082015282526000199092019101816118f15750506040805160a081018252600181526001600160a01b0388811660208301526000928201839052606082018390528916608082015282519293509183919061197457611974614a07565b6020908102919091010152604080516001808252818301909252600091816020015b6040805160c08101825260008082526020808301829052928201819052606082018190526080820181905260a082015282526000199092019101816119965750506040805160c0810182526004815260056020820152600a91810191909152601e60608201526000608082018190526001600160a01b038a1660a083015282519293509091839190611a2a57611a2a614a07565b60209081029190910101526004546000908190611a7090869067ffffffffffffffff811690700100000000000000000000000000000000900463ffffffff168787613479565b91509150600080516020615b4683398151915282604051611a9391815260200190565b60405180910390a160168214611aa857600080fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050505050565b6040516001600160a01b038381166024830152821660448201526000908190819061016790638f8d7f9960e01b9060640161124c565b6000611b39611b348385614bcc565b6135ad565b9050600080516020615b4683398151915281604051610b8691815260200190565b6000611b65826135d7565b9050600080516020615b4683398151915281604051611b8691815260200190565b60405180910390a160168114611b9b57600080fd5b919050565b604051633cb0c7fd60e21b81526001600160a01b038084166004830152821660248201526000908190309063f2c31ff4906044016040805180830381600087803b158015611bed57600080fd5b505af1158015611c01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c259190614d44565b604051600783900b81529193509150600080516020615b468339815191529060200160405180910390a1600782900b601614611c6057600080fd5b60405181151581527fd24dda6928587354b65aa1a18c2eaf249bef7e5bafd2a71fac71d286f76f957f90602001610a5b565b6040516001600160a01b03838116602483015282166044820152600090819081906101679063af99c63360e01b9060640161124c565b60408051606081018252600080825260208201819052918101829052604051631ac299b760e31b81526001600160a01b0384166004820152309063d614cdb890602401608060405180830381600087803b158015611d2557600080fd5b505af1158015611d39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d5d9190614dd3565b6040518281529193509150600080516020615b468339815191529060200160405180910390a160168214611d9057600080fd5b7fa0a16bf9db2c17796faeca5af5aaeef8523f9d4c350c512cb00062ad89604f8881604051610d199190614e00565b604080516060810182526000808252602080830182905282840182905283516001600160a01b038616602480830191909152855180830390910181526044909101855290810180516001600160e01b0316631ac299b760e31b179052925190928391829161016791611e3191906149be565b6000604051808303816000865af19150503d8060008114611e6e576040519150601f19603f3d011682016040523d82523d6000602084013e611e73565b606091505b506040805160608101825260008082526020820181905291810191909152919350915082611ea357601581611eb7565b81806020019051810190611eb79190614e34565b60039190910b97909650945050505050565b60408051600580825260c08201909252600091816020015b611ee9613ac3565b815260200190600190039081611ee1579050509050611f1c60006006600160405180602001604052806000815250612adf565b81600081518110611f2f57611f2f614a07565b6020026020010181905250611f5560018060405180602001604052806000815250612b16565b81600181518110611f6857611f68614a07565b6020026020010181905250611f8f6002600160405180602001604052806000815250612b16565b81600281518110611fa257611fa2614a07565b6020026020010181905250611fc96004600160405180602001604052806000815250612b16565b81600381518110611fdc57611fdc614a07565b60200260200101819052506120036003600160405180602001604052806000815250612b16565b8160048151811061201657612016614a07565b602002602001018190525060006040518060600160405280600063ffffffff168152602001846001600160a01b03168152602001627a120063ffffffff16815250905060006040518061012001604052806001805461207490614a1d565b80601f01602080910402602001604051908101604052809291908181526020018280546120a090614a1d565b80156120ed5780601f106120c2576101008083540402835291602001916120ed565b820191906000526020600020905b8154815290600101906020018083116120d057829003601f168201915b505050505081526020016002805461210490614a1d565b80601f016020809104026020016040519081016040528092919081815260200182805461213090614a1d565b801561217d5780601f106121525761010080835404028352916020019161217d565b820191906000526020600020905b81548152906001019060200180831161216057829003601f168201915b50505050508152602001856001600160a01b03168152602001600380546121a390614a1d565b80601f01602080910402602001604051908101604052809291908181526020018280546121cf90614a1d565b801561221c5780601f106121f15761010080835404028352916020019161221c565b820191906000526020600020905b8154815290600101906020018083116121ff57829003601f168201915b50505091835250506001602082015260045468010000000000000000810460070b6040830152600160a01b900460ff16151560608201526080810185905260a00183905290506000806110be8361361e565b60006111e3848484613708565b6040517f593d6e82000000000000000000000000000000000000000000000000000000008152600090309063593d6e82906122bc9086908690600401614a6b565b602060405180830381600087803b1580156122d657600080fd5b505af11580156122ea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3991906149a5565b60006111e3848484613763565b6040516001600160a01b0383811660248301528216604482015260009081908190819061016790633cb0c7fd60e21b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161238d91906149be565b6000604051808303816000865af19150503d80600081146123ca576040519150601f19603f3d011682016040523d82523d6000602084013e6123cf565b606091505b5091509150816123e25760156000611eb7565b80806020019051810190611eb79190614e5f565b6000612400613b7b565b612409836137ba565b6040518281529193509150600080516020615b468339815191529060200160405180910390a16016821461243c57600080fd5b7fbdb65f8c2a2e9a3a37ea49e903836883766a922e4ce9b21f684035e304962d4181604051610d199190614e8b565b6000611b3983836138a3565b604051633b3bff0f60e01b81526001600160a01b03821660048201526000903090633b3bff0f90602401602060405180830381600087803b1580156124bb57600080fd5b505af11580156124cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f391906149a5565b9050600080516020615b468339815191528160405161251491815260200190565b60405180910390a16016811461252957600080fd5b604051600181527f319ab7084208e4afa38c6e6ff7aea9587439f2e4700746f4c7d425fea17426d290602001610b49565b60006111e38484846138f2565b600480547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b8315158102919091179182905560405160ff9190920416151581527f457c3a16a0ebdc38e3675609957ca3fcc4490e220bd15d85d34f58e2e145cb089060200160405180910390a150565b60408051600080825260208201909252819081612622565b60408051606081018252600080825260208083018290529282015282526000199092019101816125f55790505b50905060006040518060400160405280336001600160a01b031681526020018561264b90614e9e565b600790810b9091526040805180820182526001600160a01b038a1681529187900b602083015280516002808252606082019092529293509091600091816020015b604080518082019091526000808252602082015281526020019060019003908161268c57905050905082816000815181106126c9576126c9614a07565b602002602001018190525081816001815181106126e8576126e8614a07565b602090810291909101810191909152604080516060810182526001600160a01b038a16815291820183905281810186905280516001808252818301909252600091816020015b61275b604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b81526020019060019003908161272e579050509050818160008151811061278457612784614a07565b6020026020010181905250612798816135ad565b9650601687146127a757600080fd5b5050505050509392505050565b604080516001600160a01b0385811660248301528481166044830152831660648083019190915282518083039091018152608490910182526020810180516001600160e01b03167ff49f40db00000000000000000000000000000000000000000000000000000000179052905160009182918291829161016791612837916149be565b6000604051808303816000865af19150503d8060008114612874576040519150601f19603f3d011682016040523d82523d6000602084013e612879565b606091505b50915091508161288c57601560006128a0565b808060200190518101906128a09190614e5f565b60039190910b9890975095505050505050565b604080516001600160a01b0384166024820152604480820184905282518083039091018152606490910182526020810180516001600160e01b03167f098f23660000000000000000000000000000000000000000000000000000000017905290516000918291829182916101679161292a916149be565b6000604051808303816000865af19150503d8060008114612967576040519150601f19603f3d011682016040523d82523d6000602084013e61296c565b606091505b50915091508161297f5760156000611eb7565b80806020019051810190611eb79190614ed4565b6040516001600160a01b0383811660248301528216604482015260009081908190610167907f52f91387000000000000000000000000000000000000000000000000000000009060640161124c565b6040516001600160a01b0382166024820152600090819081908190610167907fa7daa18d00000000000000000000000000000000000000000000000000000000906044015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612a6591906149be565b6000604051808303816000865af19150503d8060008114612aa2576040519150601f19603f3d011682016040523d82523d6000602084013e612aa7565b606091505b509150915081612aba5760156000612ace565b80806020019051810190612ace9190614e5f565b60039190910b969095509350505050565b612ae7613ac3565b6040518060400160405280612afc8787613948565b8152602001612b0b8585613961565b905295945050505050565b612b1e613ac3565b6040518060400160405280612b3286613a31565b8152602001612b418585613961565b9052949350505050565b600080848061010001516000015163ffffffff166000148015612b7b57506101008101516040015163ffffffff16155b15612b91576101008101516276a7006040909101525b6000806101676001600160a01b03163463c23baeb660e01b8a8a8a604051602401612bbe93929190614f00565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612bfc91906149be565b60006040518083038185875af1925050503d8060008114612c39576040519150601f19603f3d011682016040523d82523d6000602084013e612c3e565b606091505b509150915081612c515760156000612c65565b80806020019051810190612c659190614ed4565b60039190910b999098509650505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b608482015260009081908190610167907feca36917000000000000000000000000000000000000000000000000000000009060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612d1491906149be565b6000604051808303816000865af19150503d8060008114612d51576040519150601f19603f3d011682016040523d82523d6000602084013e612d56565b606091505b509150915081612d67576015612d7b565b80806020019051810190612d7b91906149ec565b60030b979650505050505050565b6000612d93613b20565b604080516001600160a01b0386166024820152600785900b60448083019190915282518083039091018152606490910182526020810180516001600160e01b03167f287e1da8000000000000000000000000000000000000000000000000000000001790529051600091829161016791612e0c916149be565b6000604051808303816000865af19150503d8060008114612e49576040519150601f19603f3d011682016040523d82523d6000602084013e612e4e565b606091505b5091509150612e5b613b20565b82612e68576015816128a0565b818060200190518101906128a0919061559e565b60008060006101676001600160a01b031663f7f38e2660e01b878787604051602401612eaa93929190615686565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612ee891906149be565b6000604051808303816000865af19150503d8060008114612f25576040519150601f19603f3d011682016040523d82523d6000602084013e612f2a565b606091505b509150915081612f3b576015612f4f565b80806020019051810190612f4f91906149ec565b60030b9695505050505050565b604080516001600160a01b0385811660248301528481166044830152831660648083019190915282518083039091018152608490910182526020810180516001600160e01b03167f927da10500000000000000000000000000000000000000000000000000000000179052905160009182918291829161016791612fdf916149be565b6000604051808303816000865af19150503d806000811461301c576040519150601f19603f3d011682016040523d82523d6000602084013e613021565b606091505b50915091508161303457601560006128a0565b808060200190518101906128a091906156b2565b604080516001600160a01b03831660248083019190915282518083039091018152604490910182526020810180516001600160e01b03167fae7611a00000000000000000000000000000000000000000000000000000000017905290516000916060918291829185918291610167916130c0916149be565b6000604051808303816000865af19150503d80600081146130fd576040519150601f19603f3d011682016040523d82523d6000602084013e613102565b606091505b509150915060608060608461311b57601583838361312f565b8380602001905181019061312f91906156de565b60039390930b9d919c509a509098509650505050505050565b6000613152613b5b565b604080516001600160a01b03851660248083019190915282518083039091018152604490910182526020810180516001600160e01b03167f3f28a19b0000000000000000000000000000000000000000000000000000000017905290516000918291610167916131c1916149be565b6000604051808303816000865af19150503d80600081146131fe576040519150601f19603f3d011682016040523d82523d6000602084013e613203565b606091505b5091509150613210613b5b565b8261321d57601581611eb7565b81806020019051810190611eb79190615777565b6040516001600160a01b03838116602483015282166044820152600090819081908190610167907f46de0fb1000000000000000000000000000000000000000000000000000000009060640161234f565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b608482015260009081908190610167907f5cfc9011000000000000000000000000000000000000000000000000000000009060a401612cd6565b6040516001600160a01b0383811660248301528216604482015260009081908190610167907f5b8f8584000000000000000000000000000000000000000000000000000000009060640161124c565b60008060606000806101676001600160a01b031663278e0b8860e01b89898960405160240161336393929190615823565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516133a191906149be565b6000604051808303816000865af19150503d80600081146133de576040519150601f19603f3d011682016040523d82523d6000602084013e6133e3565b606091505b50915091508161340657604080516000808252602082019092526015919061341a565b8080602001905181019061341a91906158a7565b60039290920b9a90995090975095505050505050565b6040516001600160a01b0382166024820152600090819081908190610167907f335e04c10000000000000000000000000000000000000000000000000000000090604401612a27565b600080868061010001516000015163ffffffff1660001480156134a957506101008101516040015163ffffffff16155b156134bf576101008101516276a7006040909101525b6000806101676001600160a01b03163463b937581a60e01b8c8c8c8c8c6040516024016134f0959493929190615958565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161352e91906149be565b60006040518083038185875af1925050503d806000811461356b576040519150601f19603f3d011682016040523d82523d6000602084013e613570565b606091505b5091509150816135835760156000613597565b808060200190518101906135979190614ed4565b60039190910b9b909a5098505050505050505050565b60008060006101676001600160a01b031663189a554c60e01b85604051602401610bfc9190615a0e565b6040516001600160a01b038216602482015260009081908190610167907ff069f7120000000000000000000000000000000000000000000000000000000090604401610bfc565b600080828061010001516000015163ffffffff16600014801561364e57506101008101516040015163ffffffff16155b15613664576101008101516276a7006040909101525b6000806101676001600160a01b031634639c89bb3560e01b8860405160240161368d9190615ae4565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516136cb91906149be565b60006040518083038185875af1925050503d8060008114612967576040519150601f19603f3d011682016040523d82523d6000602084013e61296c565b6040516001600160a01b0384811660248301528316604482015263ffffffff8216606482015260009081908190610167907f9790686d0000000000000000000000000000000000000000000000000000000090608401612eaa565b6040516001600160a01b03848116602483015283166044820152811515606482015260009081908190610167907f367605ca0000000000000000000000000000000000000000000000000000000090608401612eaa565b60006137c4613b7b565b604080516001600160a01b03851660248083019190915282518083039091018152604490910182526020810180516001600160e01b03167f1f69565f000000000000000000000000000000000000000000000000000000001790529051600091829161016791613833916149be565b6000604051808303816000865af19150503d8060008114613870576040519150601f19603f3d011682016040523d82523d6000602084013e613875565b606091505b5091509150613882613b7b565b8261388f57601581611eb7565b81806020019051810190611eb79190615af7565b6040516001600160a01b0383811660248301528216604482015260009081908190610167907f49146bde000000000000000000000000000000000000000000000000000000009060640161124c565b6040516001600160a01b038481166024830152831660448201526064810182905260009081908190610167907fe1f21c670000000000000000000000000000000000000000000000000000000090608401612eaa565b6000600160ff84161b9050600160ff83161b8117611219565b6139a76040518060a0016040528060001515815260200160006001600160a01b03168152602001606081526020016060815260200160006001600160a01b031681525090565b8260ff16600114156139bc5760018152610962565b8260ff16600214156139de576000546001600160a01b03166020820152610962565b8260ff16600314156139f65760408101829052610962565b8260ff1660041415613a0e5760608101829052610962565b8260ff1660051415610962576000546001600160a01b0316608082015292915050565b600060ff8216613a4357506001919050565b8160ff1660011415613a5757506002919050565b8160ff1660021415613a6b57506004919050565b8160ff1660031415613a7f57506008919050565b8160ff1660041415613a9357506010919050565b8160ff1660051415613aa757506020919050565b8160ff1660061415613abb57506040919050565b506000919050565b604051806040016040528060008152602001613b1b6040518060a0016040528060001515815260200160006001600160a01b03168152602001606081526020016060815260200160006001600160a01b031681525090565b905290565b6040518060c00160405280613b33613b7b565b8152600060208201819052604082018190526060808301829052608083015260a09091015290565b6040518060400160405280613b6e613b7b565b8152600060209091015290565b60408051610240810182526060610120820181815261014083018290526000610160840181905261018084018390526101a084018190526101c084018190526101e0840181905261020084018390528451928301855280835260208301819052938201939093526102208201529081908152602001600067ffffffffffffffff168152602001600015158152602001600015158152602001600015158152602001606081526020016060815260200160608152602001606081525090565b6001600160a01b0381168114613c4e57600080fd5b50565b60008060408385031215613c6457600080fd5b8235613c6f81613c39565b91506020830135613c7f81613c39565b809150509250929050565b600080600060608486031215613c9f57600080fd5b8335613caa81613c39565b92506020840135613cba81613c39565b91506040840135613cca81613c39565b809150509250925092565b60008060408385031215613ce857600080fd5b8235613cf381613c39565b946020939093013593505050565b600060208284031215613d1357600080fd5b813561121981613c39565b8060070b8114613c4e57600080fd5b60008060008060808587031215613d4357600080fd5b8435613d4e81613c39565b93506020850135613d5e81613c39565b92506040850135613d6e81613c39565b91506060850135613d7e81613d1e565b939692955090935050565b60008060408385031215613d9c57600080fd5b8235613da781613c39565b91506020830135613c7f81613d1e565b60005b83811015613dd2578181015183820152602001613dba565b83811115613de1576000848401525b50505050565b60008151808452613dff816020860160208601613db7565b601f01601f19169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015613eca5782840389528151604081518652868201519150808787015281511515818701528682015160606001600160a01b03808316828a015283850151935060a09250608083818b0152613e8c60e08b0186613de7565b928601518a8403603f1901858c0152929450613ea88584613de7565b9501511660c09890980197909752505098850198935090840190600101613e31565b5091979650505050505050565b60006101608251818552613eed82860182613de7565b91505060208301518482036020860152613f078282613de7565b9150506040830151613f2460408601826001600160a01b03169052565b5060608301518482036060860152613f3c8282613de7565b9150506080830151613f52608086018215159052565b5060a0830151613f6760a086018260070b9052565b5060c0830151613f7b60c086018215159052565b5060e083015184820360e0860152613f938282613e13565b61010085810151805163ffffffff9081168984015260208201516001600160a01b03166101208a015260408201511661014089015291935091505090949350505050565b600081518084526020808501945080840160005b83811015614047578151805163ffffffff168852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a09096019590820190600101613feb565b509495945050505050565b600081518084526020808501945080840160005b83811015614047578151805163ffffffff9081168952848201518116858a01526040808301518216908a01526060808301519091169089015260808082015115159089015260a0908101516001600160a01b03169088015260c09096019590820190600101614066565b600081518084526020808501945080840160005b83811015614047578151805163ffffffff9081168952848201518116858a0152604080830151909116908901526060808201516001600160a01b03908116918a01919091526080808301511515908a015260a091820151169088015260c090960195908201906001016140e4565b6000610120825181855261416882860182613ed7565b9150506020830151614186602086018267ffffffffffffffff169052565b50604083015161419a604086018215159052565b5060608301516141ae606086018215159052565b5060808301516141c2608086018215159052565b5060a083015184820360a08601526141da8282613fd7565b91505060c083015184820360c08601526141f48282614052565b91505060e083015184820360e086015261420e82826140d0565b91505061010080840151858303828701526142298382613de7565b9695505050505050565b6000815160c0845261424860c0850182614152565b9050602083015160070b602085015260408301516001600160a01b038082166040870152606085015160070b60608701526080850151915085830360808701526142928383613de7565b92508060a08601511660a087015250508091505092915050565b8281526040602082015260006111586040830184614233565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156142fe576142fe6142c5565b60405290565b6040805190810167ffffffffffffffff811182821017156142fe576142fe6142c5565b60405160a0810167ffffffffffffffff811182821017156142fe576142fe6142c5565b604051610120810167ffffffffffffffff811182821017156142fe576142fe6142c5565b60405160c0810167ffffffffffffffff811182821017156142fe576142fe6142c5565b604051601f8201601f1916810167ffffffffffffffff811182821017156143ba576143ba6142c5565b604052919050565b600067ffffffffffffffff8211156143dc576143dc6142c5565b5060051b60200190565b6000806000606084860312156143fb57600080fd5b833561440681613c39565b925060208481013561441781613c39565b9250604085013567ffffffffffffffff81111561443357600080fd5b8501601f8101871361444457600080fd5b8035614457614452826143c2565b614391565b81815260059190911b8201830190838101908983111561447657600080fd5b928401925b8284101561449d57833561448e81613d1e565b8252928401929084019061447b565b80955050505050509250925092565b63ffffffff81168114613c4e57600080fd5b60008082840360808112156144d257600080fd5b83356144dd81613c39565b92506060601f19820112156144f157600080fd5b506144fa6142db565b6020840135614508816144ac565b8152604084013561451881613c39565b6020820152606084013561452b816144ac565b6040820152919491935090915050565b8460070b81526080602082015260006145576080830186613fd7565b82810360408401526145698186614052565b9050828103606084015261457d81856140d0565b979650505050505050565b600081516040845261459d6040850182614152565b60209384015163ffffffff16949093019390935250919050565b8281526040602082015260006111586040830184614588565b67ffffffffffffffff81168114613c4e57600080fd5b600067ffffffffffffffff821115614600576146006142c5565b50601f01601f191660200190565b60008060006060848603121561462357600080fd5b833561462e81613c39565b925060208481013561463f816145d0565b925060408581013567ffffffffffffffff8082111561465d57600080fd5b818801915088601f83011261467157600080fd5b813561467f614452826143c2565b81815260059190911b8301850190858101908b83111561469e57600080fd5b8685015b83811015614712578035858111156146ba5760008081fd5b8601603f81018e136146cc5760008081fd5b888101356146dc614452826145e6565b8181528f8a8385010111156146f15760008081fd5b818a84018c83013760009181018b01919091528452509187019187016146a2565b50809750505050505050509250925092565b600081518084526020808501945080840160005b8381101561404757815160070b87529582019590820190600101614738565b83815267ffffffffffffffff831660208201526060604082015260006147806060830184614724565b95945050505050565b6000806020838503121561479c57600080fd5b823567ffffffffffffffff808211156147b457600080fd5b818501915085601f8301126147c857600080fd5b8135818111156147d757600080fd5b8660208260051b85010111156147ec57600080fd5b60209290920196919550909350505050565b828152608081016112196020830184805163ffffffff90811683526020808301516001600160a01b03169084015260409182015116910152565b60008060006060848603121561484d57600080fd5b833561485881613c39565b9250602084013561486881613c39565b91506040840135613cca816144ac565b8015158114613c4e57600080fd5b60008060006060848603121561489b57600080fd5b83356148a681613c39565b925060208401356148b681613c39565b91506040840135613cca81614878565b8281526040602082015260006111586040830184614152565b6000806000606084860312156148f457600080fd5b83356148ff81613c39565b9250602084013561490f81613c39565b929592945050506040919091013590565b60006020828403121561493257600080fd5b813561121981614878565b60008060006060848603121561495257600080fd5b833561495d81613c39565b9250602084013561496d81613c39565b91506040840135613cca81613d1e565b8051611b9b81613d1e565b60006020828403121561499a57600080fd5b815161121981613d1e565b6000602082840312156149b757600080fd5b5051919050565b600082516149d0818460208701613db7565b9190910192915050565b8051600381900b8114611b9b57600080fd5b6000602082840312156149fe57600080fd5b611219826149da565b634e487b7160e01b600052603260045260246000fd5b600181811c90821680614a3157607f821691505b60208210811415614a5257634e487b7160e01b600052602260045260246000fd5b50919050565b6020815260006112196020830184614233565b6001600160a01b0383168152608081016112196020830184805163ffffffff90811683526020808301516001600160a01b03169084015260409182015116910152565b606081526000614ac16060830186613fd7565b8281036020840152614ad38186614052565b9050828103604084015261422981856140d0565b6020815260006112196020830184614588565b67ffffffffffffffff831681526040602082015260006111586040830184614724565b600082601f830112614b2e57600080fd5b81356020614b3e614452836143c2565b82815260609283028501820192828201919087851115614b5d57600080fd5b8387015b85811015614bbf5781818a031215614b795760008081fd5b614b816142db565b8135614b8c81613c39565b815281860135614b9b81613c39565b81870152604082810135614bae81613d1e565b908201528452928401928101614b61565b5090979650505050505050565b6000614bda614452846143c2565b80848252602080830192508560051b850136811115614bf857600080fd5b855b81811015614d2d57803567ffffffffffffffff80821115614c1b5760008081fd5b818901915060608236031215614c315760008081fd5b614c396142db565b8235614c4481613c39565b81528286013582811115614c585760008081fd5b830136601f820112614c6a5760008081fd5b8035614c78614452826143c2565b81815260069190911b82018801908881019036831115614c985760008081fd5b928901925b82841015614cee5760408436031215614cb65760008081fd5b614cbe614304565b8435614cc981613c39565b8152848b0135614cd881613d1e565b818c015282526040939093019290890190614c9d565b848a01525060409150508381013583811115614d0a5760008081fd5b614d1636828701614b1d565b918301919091525087525050938201938201614bfa565b50919695505050505050565b8051611b9b81614878565b60008060408385031215614d5757600080fd5b8251614d6281613d1e565b6020840151909250613c7f81614878565b8051611b9b81613c39565b600060608284031215614d9057600080fd5b614d986142db565b90508151614da5816144ac565b81526020820151614db581613c39565b60208201526040820151614dc8816144ac565b604082015292915050565b60008060808385031215614de657600080fd5b82519150614df78460208501614d7e565b90509250929050565b606081016109628284805163ffffffff90811683526020808301516001600160a01b03169084015260409182015116910152565b60008060808385031215614e4757600080fd5b614e50836149da565b9150614df78460208501614d7e565b60008060408385031215614e7257600080fd5b614e7b836149da565b91506020830151613c7f81614878565b6020815260006112196020830184614152565b60008160070b677fffffffffffffff19811415614ecb57634e487b7160e01b600052601160045260246000fd5b60000392915050565b60008060408385031215614ee757600080fd5b614ef0836149da565b91506020830151613c7f81613c39565b606081526000614f136060830186613ed7565b905067ffffffffffffffff8416602083015263ffffffff83166040830152949350505050565b600082601f830112614f4a57600080fd5b8151614f58614452826145e6565b818152846020838601011115614f6d57600080fd5b611158826020830160208701613db7565b600082601f830112614f8f57600080fd5b81516020614f9f614452836143c2565b82815260059290921b84018101918181019086841115614fbe57600080fd5b8286015b848110156150d457805167ffffffffffffffff80821115614fe257600080fd5b908801906040601f19838c038101821315614ffc57600080fd5b615004614304565b888501518152828501518481111561501b57600080fd5b949094019360a0858e03830112156150335760008081fd5b61503b614327565b91508885015161504a81614878565b82528483015161505981613c39565b828a0152606085810151858111156150715760008081fd5b61507f8f8c838a0101614f39565b858501525060809350838601518581111561509a5760008081fd5b6150a88f8c838a0101614f39565b8285015250506150ba60a08601614d73565b928201929092528188015285525050918301918301614fc2565b509695505050505050565b600061016082840312156150f257600080fd5b6150fa61434a565b9050815167ffffffffffffffff8082111561511457600080fd5b61512085838601614f39565b8352602084015191508082111561513657600080fd5b61514285838601614f39565b602084015261515360408501614d73565b6040840152606084015191508082111561516c57600080fd5b61517885838601614f39565b606084015261518960808501614d39565b608084015261519a60a0850161497d565b60a08401526151ab60c08501614d39565b60c084015260e08401519150808211156151c457600080fd5b506151d184828501614f7e565b60e0830152506101006151e684828501614d7e565b9082015292915050565b8051611b9b816145d0565b600082601f83011261520c57600080fd5b8151602061521c614452836143c2565b82815260a0928302850182019282820191908785111561523b57600080fd5b8387015b85811015614bbf5781818a0312156152575760008081fd5b61525f614327565b815161526a816144ac565b81528186015161527981613c39565b8187015260408281015161528c81614878565b9082015260608281015161529f81614878565b908201526080828101516152b281613c39565b90820152845292840192810161523f565b600082601f8301126152d457600080fd5b815160206152e4614452836143c2565b82815260c0928302850182019282820191908785111561530357600080fd5b8387015b85811015614bbf5781818a03121561531f5760008081fd5b61532761436e565b8151615332816144ac565b815281860151615341816144ac565b81870152604082810151615354816144ac565b90820152606082810151615367816144ac565b9082015260808281015161537a81614878565b9082015260a08281015161538d81613c39565b908201528452928401928101615307565b600082601f8301126153af57600080fd5b815160206153bf614452836143c2565b82815260c092830285018201928282019190878511156153de57600080fd5b8387015b85811015614bbf5781818a0312156153fa5760008081fd5b61540261436e565b815161540d816144ac565b81528186015161541c816144ac565b8187015260408281015161542f816144ac565b9082015260608281015161544281613c39565b9082015260808281015161545581614878565b9082015260a08281015161546881613c39565b9082015284529284019281016153e2565b6000610120828403121561548c57600080fd5b61549461434a565b9050815167ffffffffffffffff808211156154ae57600080fd5b6154ba858386016150df565b83526154c8602085016151f0565b60208401526154d960408501614d39565b60408401526154ea60608501614d39565b60608401526154fb60808501614d39565b608084015260a084015191508082111561551457600080fd5b615520858386016151fb565b60a084015260c084015191508082111561553957600080fd5b615545858386016152c3565b60c084015260e084015191508082111561555e57600080fd5b61556a8583860161539e565b60e08401526101009150818401518181111561558557600080fd5b61559186828701614f39565b8385015250505092915050565b600080604083850312156155b157600080fd5b6155ba836149da565b9150602083015167ffffffffffffffff808211156155d757600080fd5b9084019060c082870312156155eb57600080fd5b6155f361436e565b82518281111561560257600080fd5b61560e88828601615479565b82525061561d6020840161497d565b602082015261562e60408401614d73565b604082015261563f6060840161497d565b606082015260808301518281111561565657600080fd5b61566288828601614f39565b60808301525061567460a08401614d73565b60a08201528093505050509250929050565b60006001600160a01b038086168352808516602084015250606060408301526147806060830184614724565b600080604083850312156156c557600080fd5b6156ce836149da565b9150602083015190509250929050565b600080600080608085870312156156f457600080fd5b6156fd856149da565b9350602085015167ffffffffffffffff8082111561571a57600080fd5b615726888389016151fb565b9450604087015191508082111561573c57600080fd5b615748888389016152c3565b9350606087015191508082111561575e57600080fd5b5061576b8782880161539e565b91505092959194509250565b6000806040838503121561578a57600080fd5b615793836149da565b9150602083015167ffffffffffffffff808211156157b057600080fd5b90840190604082870312156157c457600080fd5b6040516040810181811083821117156157df576157df6142c5565b6040528251828111156157f157600080fd5b6157fd88828601615479565b82525060208301519250615810836144ac565b8260208201528093505050509250929050565b6000606082016001600160a01b0386168352602067ffffffffffffffff8616818501526060604085015281855180845260808601915060808160051b870101935082870160005b8281101561589857607f19888703018452615886868351613de7565b9550928401929084019060010161586a565b50939998505050505050505050565b6000806000606084860312156158bc57600080fd5b6158c5846149da565b92506020808501516158d6816145d0565b604086015190935067ffffffffffffffff8111156158f357600080fd5b8501601f8101871361590457600080fd5b8051615912614452826143c2565b81815260059190911b8201830190838101908983111561593157600080fd5b928401925b8284101561449d57835161594981613d1e565b82529284019290840190615936565b60a08152600061596b60a0830188613ed7565b67ffffffffffffffff8716602084015263ffffffff8616604084015282810360608401526159998186613fd7565b905082810360808401526159ad8185614052565b98975050505050505050565b600081518084526020808501945080840160005b8381101561404757815180516001600160a01b03908116895284820151168489015260409081015160070b90880152606090960195908201906001016159cd565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b84811015615ad557898403603f19018652825180516001600160a01b0390811686528982015160608b880181905281519088018190526080880192918c01919086905b80821015615aa75783518051841686528e015160070b8e860152938c0193928d019260019190910190615a79565b5050505090880151858203868a015290615ac181836159b9565b978a01979550505091870191600101615a36565b50919998505050505050505050565b6020815260006112196020830184613ed7565b60008060408385031215615b0a57600080fd5b615b13836149da565b9150602083015167ffffffffffffffff811115615b2f57600080fd5b615b3b85828601615479565b915050925092905056fe90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aaa26469706673582212209b2868512f7ada058e50140bc7190fa533d71748a7da3f3bddc48212a1d566c664736f6c63430008090033", - "deployedBytecode": "0x6080604052600436106102c65760003560e01c80638070905f11610179578063d85f74c1116100d6578063f2f38a741161008a578063f848fec411610064578063f848fec414610844578063f9e978bd14610864578063fdc8321e1461088457600080fd5b8063f2f38a74146107d6578063f4a01e5b14610804578063f7be34251461082457600080fd5b8063eee55ac8116100bb578063eee55ac814610776578063f25b120014610796578063f2c31ff4146107b657600080fd5b8063d85f74c114610743578063d92ac2481461075657600080fd5b8063a345f7bd1161012d578063af99c63311610112578063af99c633146106d5578063c0b19b6d146106f5578063d614cdb81461072357600080fd5b8063a345f7bd1461067b578063a3ad5b551461069b57600080fd5b80638ba74da01161015e5780638ba74da0146106285780638f8d7f991461063b5780639604ca651461065b57600080fd5b80638070905f146105d957806386f88d881461060857600080fd5b80634cbdb37b1161022757806369837dc2116101db5780636da6b1f0116101c05780636da6b1f0146105795780637c41ad2c146105995780637d3e5da8146105b957600080fd5b806369837dc21461052b5780636a4dde211461055957600080fd5b8063593d6e821161020c578063593d6e82146104a65780635a5e6c31146104c65780635b9076b7146104fb57600080fd5b80634cbdb37b1461045857806356af84031461048657600080fd5b80632eecbca31161027e5780633eed2c39116102635780633eed2c39146104035780634b5c6687146104235780634ba670351461043857600080fd5b80632eecbca3146103c35780633b3bff0f146103e357600080fd5b806319db44b6116102af57806319db44b6146103385780632b256ec8146103755780632d73bb2e146103a357600080fd5b80630fd2601e146102cb57806313c05dd814610303575b600080fd5b3480156102d757600080fd5b506102eb6102e6366004613c51565b6108a4565b60405160079190910b81526020015b60405180910390f35b34801561030f57600080fd5b5061032361031e366004613c8a565b610968565b604080519283529015156020830152016102fa565b34801561034457600080fd5b50610358610353366004613cd5565b6109e6565b604080519283526001600160a01b039091166020830152016102fa565b34801561038157600080fd5b50610395610390366004613d01565b610a6a565b6040519081526020016102fa565b3480156103af57600080fd5b506103956103be366004613c51565b610b56565b3480156103cf57600080fd5b506102eb6103de366004613c51565b610b9b565b3480156103ef57600080fd5b506103956103fe366004613d01565b610bd2565b34801561040f57600080fd5b5061032361041e366004613d01565b610cac565b610436610431366004613d01565b610d26565b005b34801561044457600080fd5b50610395610453366004613d2d565b611114565b34801561046457600080fd5b50610478610473366004613d89565b611160565b6040516102fa9291906142ac565b34801561049257600080fd5b506103956104a13660046143e6565b6111d6565b3480156104b257600080fd5b506103956104c13660046144be565b611220565b3480156104d257600080fd5b506104e66104e1366004613c8a565b6112fd565b604080519283526020830191909152016102fa565b34801561050757600080fd5b5061051b610516366004613d01565b61136e565b6040516102fa949392919061453b565b34801561053757600080fd5b5061054b610546366004613d01565b611400565b6040516102fa9291906145b7565b34801561056557600080fd5b50610323610574366004613c51565b611475565b34801561058557600080fd5b50610395610594366004613d2d565b6114ec565b3480156105a557600080fd5b506103956105b4366004613d01565b6114fa565b3480156105c557600080fd5b506103956105d4366004613c51565b611528565b3480156105e557600080fd5b506105f96105f436600461460e565b611534565b6040516102fa93929190614757565b34801561061457600080fd5b50610323610623366004613d01565b6115bc565b610436610636366004613c51565b61162d565b34801561064757600080fd5b506102eb610656366004613c51565b611aef565b34801561066757600080fd5b50610395610676366004614789565b611b25565b34801561068757600080fd5b50610395610696366004613d01565b611b5a565b3480156106a757600080fd5b506106bb6106b6366004613c51565b611ba0565b6040805160079390930b83529015156020830152016102fa565b3480156106e157600080fd5b506102eb6106f0366004613c51565b611c92565b34801561070157600080fd5b50610715610710366004613d01565b611cc8565b6040516102fa9291906147fe565b34801561072f57600080fd5b5061071561073e366004613d01565b611dbf565b610436610751366004613d01565b611ec9565b34801561076257600080fd5b50610395610771366004614838565b61226e565b34801561078257600080fd5b506103956107913660046144be565b61227b565b3480156107a257600080fd5b506103956107b1366004614886565b61230e565b3480156107c257600080fd5b506106bb6107d1366004613c51565b61231b565b3480156107e257600080fd5b506107f66107f1366004613d01565b6123f6565b6040516102fa9291906148c6565b34801561081057600080fd5b5061039561081f366004613c51565b61246b565b34801561083057600080fd5b5061039561083f366004613d01565b612477565b34801561085057600080fd5b5061039561085f3660046148df565b61255a565b34801561087057600080fd5b5061043661087f366004614920565b612567565b34801561089057600080fd5b5061039561089f36600461493d565b6125dd565b604051638f8d7f9960e01b81526001600160a01b038084166004830152821660248201526000903090638f8d7f99906044015b602060405180830381600087803b1580156108f157600080fd5b505af1158015610905573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109299190614988565b604051600782900b8152909150600080516020615b468339815191529060200160405180910390a1600781900b60161461096257600080fd5b92915050565b6000806109768585856127b4565b6040518281529193509150600080516020615b468339815191529060200160405180910390a1601682146109a957600080fd5b60405181151581527e1c2e72360171244b3bb8cc8ddd767820edf37138ad6f129fb3574b407c307d906020015b60405180910390a1935093915050565b6000806109f384846128b3565b6040518281529193509150600080516020615b468339815191529060200160405180910390a160168214610a2657600080fd5b6040516001600160a01b03821681527fc2c78c7c31baf14949e75c51df12be56edb9af523cf82839c2869bbcf13b3ecb906020015b60405180910390a19250929050565b604051631f106b4b60e21b81526001600160a01b03821660048201526000903090637c41ad2c90602401602060405180830381600087803b158015610aae57600080fd5b505af1158015610ac2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae691906149a5565b9050600080516020615b4683398151915281604051610b0791815260200190565b60405180910390a160168114610b1c57600080fd5b604051600181527f0c9c765845f4d139956bb8fc8decb2eec6093c9c608b809641b16054b29f0e13906020015b60405180910390a1919050565b6000610b628383612993565b60070b9050600080516020615b4683398151915281604051610b8691815260200190565b60405180910390a16016811461096257600080fd5b60405163af99c63360e01b81526001600160a01b03808416600483015282166024820152600090309063af99c633906044016108d7565b6040516001600160a01b03821660248201526000908190819061016790633b3bff0f60e01b906044015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610c3a91906149be565b6000604051808303816000865af19150503d8060008114610c77576040519150601f19603f3d011682016040523d82523d6000602084013e610c7c565b606091505b509150915081610c8d576015610ca1565b80806020019051810190610ca191906149ec565b60030b949350505050565b600080610cb8836129e2565b6040518281529193509150600080516020615b468339815191529060200160405180910390a160168214610ceb57600080fd5b60405181151581527f6b7f3306751292f85ab4161ee2b0ac16dfc8ded13e6446ce6bd859d0a2f4c78e906020015b60405180910390a1915091565b60408051600480825260a08201909252600091816020015b610d46613ac3565b815260200190600190039081610d3e579050509050610d7960006006600160405180602001604052806000815250612adf565b81600081518110610d8c57610d8c614a07565b6020026020010181905250610db260018060405180602001604052806000815250612b16565b81600181518110610dc557610dc5614a07565b6020026020010181905250610dec6002600160405180602001604052806000815250612b16565b81600281518110610dff57610dff614a07565b6020026020010181905250610e266003600160405180602001604052806000815250612b16565b81600381518110610e3957610e39614a07565b602002602001018190525060006040518060600160405280600063ffffffff168152602001846001600160a01b03168152602001627a120063ffffffff168152509050600060405180610120016040528060018054610e9790614a1d565b80601f0160208091040260200160405190810160405280929190818152602001828054610ec390614a1d565b8015610f105780601f10610ee557610100808354040283529160200191610f10565b820191906000526020600020905b815481529060010190602001808311610ef357829003601f168201915b5050505050815260200160028054610f2790614a1d565b80601f0160208091040260200160405190810160405280929190818152602001828054610f5390614a1d565b8015610fa05780601f10610f7557610100808354040283529160200191610fa0565b820191906000526020600020905b815481529060010190602001808311610f8357829003601f168201915b50505050508152602001856001600160a01b0316815260200160038054610fc690614a1d565b80601f0160208091040260200160405190810160405280929190818152602001828054610ff290614a1d565b801561103f5780601f106110145761010080835404028352916020019161103f565b820191906000526020600020905b81548152906001019060200180831161102257829003601f168201915b50505091835250506001602082015260045468010000000000000000810460070b6040830152600160a01b810460ff16151560608301526080820186905260a090910184905290915060009081906110be90849067ffffffffffffffff811690700100000000000000000000000000000000900463ffffffff16612b4b565b9092509050601682146110d057600080fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050565b600061112285858585612c79565b9050600080516020615b468339815191528160405161114391815260200190565b60405180910390a16016811461115857600080fd5b949350505050565b600061116a613b20565b6111748484612d89565b6040518281529193509150600080516020615b468339815191529060200160405180910390a1601682146111a757600080fd5b7fd010ef68d3ac3e07c14bed496400730a484fd17c48a4d373cbc4722a56540def81604051610a5b9190614a58565b60006111e3848484612e7c565b9050600080516020615b468339815191528160405161120491815260200190565b60405180910390a16016811461121957600080fd5b9392505050565b60008060006101676001600160a01b031663593d6e8260e01b868660405160240161124c929190614a6b565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161128a91906149be565b6000604051808303816000865af19150503d80600081146112c7576040519150601f19603f3d011682016040523d82523d6000602084013e6112cc565b606091505b5091509150816112dd5760156112f1565b808060200190518101906112f191906149ec565b60030b95945050505050565b60008061130b858585612f5c565b6040518281529193509150600080516020615b468339815191529060200160405180910390a16016821461133e57600080fd5b6040518181527f25b6684a7e8fe1b676e9c39c8dd65034fbafea906d3bdfd97bf748b7b55e14c8906020016109d6565b6000606080606061137e85613048565b604051600785900b815293975091955093509150600080516020615b468339815191529060200160405180910390a1600784900b6016146113be57600080fd5b7f2efc8334b040613a552197fe34283d6ca2909c8ffae393e128424931f20c69b38383836040516113f193929190614aae565b60405180910390a19193509193565b600061140a613b5b565b61141383613148565b6040518281529193509150600080516020615b468339815191529060200160405180910390a16016821461144657600080fd5b7fea9419ffbaa766adf982c4c9864330eee1d848eff36c79e510e7e589c8bb265f81604051610d199190614ae7565b6000806114828484613231565b60405160079290920b80835293509150600080516020615b468339815191529060200160405180910390a1601682146114ba57600080fd5b60405181151581527f59800d968fcce138300a0019410b4b75041610d65b3cdc5f31656b03ed14912e90602001610a5b565b600061112285858585613282565b6040516001600160a01b03821660248201526000908190819061016790631f106b4b60e21b90604401610bfc565b6000610b6283836132e3565b6000806060611544868686613332565b6040518381529295509093509150600080516020615b468339815191529060200160405180910390a16016831461157a57600080fd5b7feff23992f47b3c101679f8b4dc9d3e242c903909dba4a453f2b2341ad463b0e282826040516115ab929190614afa565b60405180910390a193509350939050565b6000806115c883613430565b6040518281529193509150600080516020615b468339815191529060200160405180910390a1601682146115fb57600080fd5b60405181151581527f9ee19e13dfa1ba8db2502e15ff56dbecdeb0e0473323fb195473ce648030a2cd90602001610d19565b604080516001808252818301909252600091816020015b61164c613ac3565b81526020019060019003908161164457905050905061167e600080600160405180602001604052806000815250612adf565b8160008151811061169157611691614a07565b602002602001018190525060006040518060600160405280600063ffffffff168152602001856001600160a01b03168152602001627a120063ffffffff1681525090506000604051806101200160405280600180546116ef90614a1d565b80601f016020809104026020016040519081016040528092919081815260200182805461171b90614a1d565b80156117685780601f1061173d57610100808354040283529160200191611768565b820191906000526020600020905b81548152906001019060200180831161174b57829003601f168201915b505050505081526020016002805461177f90614a1d565b80601f01602080910402602001604051908101604052809291908181526020018280546117ab90614a1d565b80156117f85780601f106117cd576101008083540402835291602001916117f8565b820191906000526020600020905b8154815290600101906020018083116117db57829003601f168201915b50505050508152602001866001600160a01b031681526020016003805461181e90614a1d565b80601f016020809104026020016040519081016040528092919081815260200182805461184a90614a1d565b80156118975780601f1061186c57610100808354040283529160200191611897565b820191906000526020600020905b81548152906001019060200180831161187a57829003601f168201915b505050918352505060016020820181905260045468010000000000000000900460070b6040808401919091526000606084018190526080840188905260a09093018690528051828152808201909152929350909190816020015b6040805160a0810182526000808252602080830182905292820181905260608201819052608082015282526000199092019101816118f15750506040805160a081018252600181526001600160a01b0388811660208301526000928201839052606082018390528916608082015282519293509183919061197457611974614a07565b6020908102919091010152604080516001808252818301909252600091816020015b6040805160c08101825260008082526020808301829052928201819052606082018190526080820181905260a082015282526000199092019101816119965750506040805160c0810182526004815260056020820152600a91810191909152601e60608201526000608082018190526001600160a01b038a1660a083015282519293509091839190611a2a57611a2a614a07565b60209081029190910101526004546000908190611a7090869067ffffffffffffffff811690700100000000000000000000000000000000900463ffffffff168787613479565b91509150600080516020615b4683398151915282604051611a9391815260200190565b60405180910390a160168214611aa857600080fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050505050565b6040516001600160a01b038381166024830152821660448201526000908190819061016790638f8d7f9960e01b9060640161124c565b6000611b39611b348385614bcc565b6135ad565b9050600080516020615b4683398151915281604051610b8691815260200190565b6000611b65826135d7565b9050600080516020615b4683398151915281604051611b8691815260200190565b60405180910390a160168114611b9b57600080fd5b919050565b604051633cb0c7fd60e21b81526001600160a01b038084166004830152821660248201526000908190309063f2c31ff4906044016040805180830381600087803b158015611bed57600080fd5b505af1158015611c01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c259190614d44565b604051600783900b81529193509150600080516020615b468339815191529060200160405180910390a1600782900b601614611c6057600080fd5b60405181151581527fd24dda6928587354b65aa1a18c2eaf249bef7e5bafd2a71fac71d286f76f957f90602001610a5b565b6040516001600160a01b03838116602483015282166044820152600090819081906101679063af99c63360e01b9060640161124c565b60408051606081018252600080825260208201819052918101829052604051631ac299b760e31b81526001600160a01b0384166004820152309063d614cdb890602401608060405180830381600087803b158015611d2557600080fd5b505af1158015611d39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d5d9190614dd3565b6040518281529193509150600080516020615b468339815191529060200160405180910390a160168214611d9057600080fd5b7fa0a16bf9db2c17796faeca5af5aaeef8523f9d4c350c512cb00062ad89604f8881604051610d199190614e00565b604080516060810182526000808252602080830182905282840182905283516001600160a01b038616602480830191909152855180830390910181526044909101855290810180516001600160e01b0316631ac299b760e31b179052925190928391829161016791611e3191906149be565b6000604051808303816000865af19150503d8060008114611e6e576040519150601f19603f3d011682016040523d82523d6000602084013e611e73565b606091505b506040805160608101825260008082526020820181905291810191909152919350915082611ea357601581611eb7565b81806020019051810190611eb79190614e34565b60039190910b97909650945050505050565b60408051600580825260c08201909252600091816020015b611ee9613ac3565b815260200190600190039081611ee1579050509050611f1c60006006600160405180602001604052806000815250612adf565b81600081518110611f2f57611f2f614a07565b6020026020010181905250611f5560018060405180602001604052806000815250612b16565b81600181518110611f6857611f68614a07565b6020026020010181905250611f8f6002600160405180602001604052806000815250612b16565b81600281518110611fa257611fa2614a07565b6020026020010181905250611fc96004600160405180602001604052806000815250612b16565b81600381518110611fdc57611fdc614a07565b60200260200101819052506120036003600160405180602001604052806000815250612b16565b8160048151811061201657612016614a07565b602002602001018190525060006040518060600160405280600063ffffffff168152602001846001600160a01b03168152602001627a120063ffffffff16815250905060006040518061012001604052806001805461207490614a1d565b80601f01602080910402602001604051908101604052809291908181526020018280546120a090614a1d565b80156120ed5780601f106120c2576101008083540402835291602001916120ed565b820191906000526020600020905b8154815290600101906020018083116120d057829003601f168201915b505050505081526020016002805461210490614a1d565b80601f016020809104026020016040519081016040528092919081815260200182805461213090614a1d565b801561217d5780601f106121525761010080835404028352916020019161217d565b820191906000526020600020905b81548152906001019060200180831161216057829003601f168201915b50505050508152602001856001600160a01b03168152602001600380546121a390614a1d565b80601f01602080910402602001604051908101604052809291908181526020018280546121cf90614a1d565b801561221c5780601f106121f15761010080835404028352916020019161221c565b820191906000526020600020905b8154815290600101906020018083116121ff57829003601f168201915b50505091835250506001602082015260045468010000000000000000810460070b6040830152600160a01b900460ff16151560608201526080810185905260a00183905290506000806110be8361361e565b60006111e3848484613708565b6040517f593d6e82000000000000000000000000000000000000000000000000000000008152600090309063593d6e82906122bc9086908690600401614a6b565b602060405180830381600087803b1580156122d657600080fd5b505af11580156122ea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3991906149a5565b60006111e3848484613763565b6040516001600160a01b0383811660248301528216604482015260009081908190819061016790633cb0c7fd60e21b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161238d91906149be565b6000604051808303816000865af19150503d80600081146123ca576040519150601f19603f3d011682016040523d82523d6000602084013e6123cf565b606091505b5091509150816123e25760156000611eb7565b80806020019051810190611eb79190614e5f565b6000612400613b7b565b612409836137ba565b6040518281529193509150600080516020615b468339815191529060200160405180910390a16016821461243c57600080fd5b7fbdb65f8c2a2e9a3a37ea49e903836883766a922e4ce9b21f684035e304962d4181604051610d199190614e8b565b6000611b3983836138a3565b604051633b3bff0f60e01b81526001600160a01b03821660048201526000903090633b3bff0f90602401602060405180830381600087803b1580156124bb57600080fd5b505af11580156124cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f391906149a5565b9050600080516020615b468339815191528160405161251491815260200190565b60405180910390a16016811461252957600080fd5b604051600181527f319ab7084208e4afa38c6e6ff7aea9587439f2e4700746f4c7d425fea17426d290602001610b49565b60006111e38484846138f2565b600480547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b8315158102919091179182905560405160ff9190920416151581527f457c3a16a0ebdc38e3675609957ca3fcc4490e220bd15d85d34f58e2e145cb089060200160405180910390a150565b60408051600080825260208201909252819081612622565b60408051606081018252600080825260208083018290529282015282526000199092019101816125f55790505b50905060006040518060400160405280336001600160a01b031681526020018561264b90614e9e565b600790810b9091526040805180820182526001600160a01b038a1681529187900b602083015280516002808252606082019092529293509091600091816020015b604080518082019091526000808252602082015281526020019060019003908161268c57905050905082816000815181106126c9576126c9614a07565b602002602001018190525081816001815181106126e8576126e8614a07565b602090810291909101810191909152604080516060810182526001600160a01b038a16815291820183905281810186905280516001808252818301909252600091816020015b61275b604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b81526020019060019003908161272e579050509050818160008151811061278457612784614a07565b6020026020010181905250612798816135ad565b9650601687146127a757600080fd5b5050505050509392505050565b604080516001600160a01b0385811660248301528481166044830152831660648083019190915282518083039091018152608490910182526020810180516001600160e01b03167ff49f40db00000000000000000000000000000000000000000000000000000000179052905160009182918291829161016791612837916149be565b6000604051808303816000865af19150503d8060008114612874576040519150601f19603f3d011682016040523d82523d6000602084013e612879565b606091505b50915091508161288c57601560006128a0565b808060200190518101906128a09190614e5f565b60039190910b9890975095505050505050565b604080516001600160a01b0384166024820152604480820184905282518083039091018152606490910182526020810180516001600160e01b03167f098f23660000000000000000000000000000000000000000000000000000000017905290516000918291829182916101679161292a916149be565b6000604051808303816000865af19150503d8060008114612967576040519150601f19603f3d011682016040523d82523d6000602084013e61296c565b606091505b50915091508161297f5760156000611eb7565b80806020019051810190611eb79190614ed4565b6040516001600160a01b0383811660248301528216604482015260009081908190610167907f52f91387000000000000000000000000000000000000000000000000000000009060640161124c565b6040516001600160a01b0382166024820152600090819081908190610167907fa7daa18d00000000000000000000000000000000000000000000000000000000906044015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612a6591906149be565b6000604051808303816000865af19150503d8060008114612aa2576040519150601f19603f3d011682016040523d82523d6000602084013e612aa7565b606091505b509150915081612aba5760156000612ace565b80806020019051810190612ace9190614e5f565b60039190910b969095509350505050565b612ae7613ac3565b6040518060400160405280612afc8787613948565b8152602001612b0b8585613961565b905295945050505050565b612b1e613ac3565b6040518060400160405280612b3286613a31565b8152602001612b418585613961565b9052949350505050565b600080848061010001516000015163ffffffff166000148015612b7b57506101008101516040015163ffffffff16155b15612b91576101008101516276a7006040909101525b6000806101676001600160a01b03163463c23baeb660e01b8a8a8a604051602401612bbe93929190614f00565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612bfc91906149be565b60006040518083038185875af1925050503d8060008114612c39576040519150601f19603f3d011682016040523d82523d6000602084013e612c3e565b606091505b509150915081612c515760156000612c65565b80806020019051810190612c659190614ed4565b60039190910b999098509650505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b608482015260009081908190610167907feca36917000000000000000000000000000000000000000000000000000000009060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612d1491906149be565b6000604051808303816000865af19150503d8060008114612d51576040519150601f19603f3d011682016040523d82523d6000602084013e612d56565b606091505b509150915081612d67576015612d7b565b80806020019051810190612d7b91906149ec565b60030b979650505050505050565b6000612d93613b20565b604080516001600160a01b0386166024820152600785900b60448083019190915282518083039091018152606490910182526020810180516001600160e01b03167f287e1da8000000000000000000000000000000000000000000000000000000001790529051600091829161016791612e0c916149be565b6000604051808303816000865af19150503d8060008114612e49576040519150601f19603f3d011682016040523d82523d6000602084013e612e4e565b606091505b5091509150612e5b613b20565b82612e68576015816128a0565b818060200190518101906128a0919061559e565b60008060006101676001600160a01b031663f7f38e2660e01b878787604051602401612eaa93929190615686565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612ee891906149be565b6000604051808303816000865af19150503d8060008114612f25576040519150601f19603f3d011682016040523d82523d6000602084013e612f2a565b606091505b509150915081612f3b576015612f4f565b80806020019051810190612f4f91906149ec565b60030b9695505050505050565b604080516001600160a01b0385811660248301528481166044830152831660648083019190915282518083039091018152608490910182526020810180516001600160e01b03167f927da10500000000000000000000000000000000000000000000000000000000179052905160009182918291829161016791612fdf916149be565b6000604051808303816000865af19150503d806000811461301c576040519150601f19603f3d011682016040523d82523d6000602084013e613021565b606091505b50915091508161303457601560006128a0565b808060200190518101906128a091906156b2565b604080516001600160a01b03831660248083019190915282518083039091018152604490910182526020810180516001600160e01b03167fae7611a00000000000000000000000000000000000000000000000000000000017905290516000916060918291829185918291610167916130c0916149be565b6000604051808303816000865af19150503d80600081146130fd576040519150601f19603f3d011682016040523d82523d6000602084013e613102565b606091505b509150915060608060608461311b57601583838361312f565b8380602001905181019061312f91906156de565b60039390930b9d919c509a509098509650505050505050565b6000613152613b5b565b604080516001600160a01b03851660248083019190915282518083039091018152604490910182526020810180516001600160e01b03167f3f28a19b0000000000000000000000000000000000000000000000000000000017905290516000918291610167916131c1916149be565b6000604051808303816000865af19150503d80600081146131fe576040519150601f19603f3d011682016040523d82523d6000602084013e613203565b606091505b5091509150613210613b5b565b8261321d57601581611eb7565b81806020019051810190611eb79190615777565b6040516001600160a01b03838116602483015282166044820152600090819081908190610167907f46de0fb1000000000000000000000000000000000000000000000000000000009060640161234f565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b608482015260009081908190610167907f5cfc9011000000000000000000000000000000000000000000000000000000009060a401612cd6565b6040516001600160a01b0383811660248301528216604482015260009081908190610167907f5b8f8584000000000000000000000000000000000000000000000000000000009060640161124c565b60008060606000806101676001600160a01b031663278e0b8860e01b89898960405160240161336393929190615823565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516133a191906149be565b6000604051808303816000865af19150503d80600081146133de576040519150601f19603f3d011682016040523d82523d6000602084013e6133e3565b606091505b50915091508161340657604080516000808252602082019092526015919061341a565b8080602001905181019061341a91906158a7565b60039290920b9a90995090975095505050505050565b6040516001600160a01b0382166024820152600090819081908190610167907f335e04c10000000000000000000000000000000000000000000000000000000090604401612a27565b600080868061010001516000015163ffffffff1660001480156134a957506101008101516040015163ffffffff16155b156134bf576101008101516276a7006040909101525b6000806101676001600160a01b03163463b937581a60e01b8c8c8c8c8c6040516024016134f0959493929190615958565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161352e91906149be565b60006040518083038185875af1925050503d806000811461356b576040519150601f19603f3d011682016040523d82523d6000602084013e613570565b606091505b5091509150816135835760156000613597565b808060200190518101906135979190614ed4565b60039190910b9b909a5098505050505050505050565b60008060006101676001600160a01b031663189a554c60e01b85604051602401610bfc9190615a0e565b6040516001600160a01b038216602482015260009081908190610167907ff069f7120000000000000000000000000000000000000000000000000000000090604401610bfc565b600080828061010001516000015163ffffffff16600014801561364e57506101008101516040015163ffffffff16155b15613664576101008101516276a7006040909101525b6000806101676001600160a01b031634639c89bb3560e01b8860405160240161368d9190615ae4565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516136cb91906149be565b60006040518083038185875af1925050503d8060008114612967576040519150601f19603f3d011682016040523d82523d6000602084013e61296c565b6040516001600160a01b0384811660248301528316604482015263ffffffff8216606482015260009081908190610167907f9790686d0000000000000000000000000000000000000000000000000000000090608401612eaa565b6040516001600160a01b03848116602483015283166044820152811515606482015260009081908190610167907f367605ca0000000000000000000000000000000000000000000000000000000090608401612eaa565b60006137c4613b7b565b604080516001600160a01b03851660248083019190915282518083039091018152604490910182526020810180516001600160e01b03167f1f69565f000000000000000000000000000000000000000000000000000000001790529051600091829161016791613833916149be565b6000604051808303816000865af19150503d8060008114613870576040519150601f19603f3d011682016040523d82523d6000602084013e613875565b606091505b5091509150613882613b7b565b8261388f57601581611eb7565b81806020019051810190611eb79190615af7565b6040516001600160a01b0383811660248301528216604482015260009081908190610167907f49146bde000000000000000000000000000000000000000000000000000000009060640161124c565b6040516001600160a01b038481166024830152831660448201526064810182905260009081908190610167907fe1f21c670000000000000000000000000000000000000000000000000000000090608401612eaa565b6000600160ff84161b9050600160ff83161b8117611219565b6139a76040518060a0016040528060001515815260200160006001600160a01b03168152602001606081526020016060815260200160006001600160a01b031681525090565b8260ff16600114156139bc5760018152610962565b8260ff16600214156139de576000546001600160a01b03166020820152610962565b8260ff16600314156139f65760408101829052610962565b8260ff1660041415613a0e5760608101829052610962565b8260ff1660051415610962576000546001600160a01b0316608082015292915050565b600060ff8216613a4357506001919050565b8160ff1660011415613a5757506002919050565b8160ff1660021415613a6b57506004919050565b8160ff1660031415613a7f57506008919050565b8160ff1660041415613a9357506010919050565b8160ff1660051415613aa757506020919050565b8160ff1660061415613abb57506040919050565b506000919050565b604051806040016040528060008152602001613b1b6040518060a0016040528060001515815260200160006001600160a01b03168152602001606081526020016060815260200160006001600160a01b031681525090565b905290565b6040518060c00160405280613b33613b7b565b8152600060208201819052604082018190526060808301829052608083015260a09091015290565b6040518060400160405280613b6e613b7b565b8152600060209091015290565b60408051610240810182526060610120820181815261014083018290526000610160840181905261018084018390526101a084018190526101c084018190526101e0840181905261020084018390528451928301855280835260208301819052938201939093526102208201529081908152602001600067ffffffffffffffff168152602001600015158152602001600015158152602001600015158152602001606081526020016060815260200160608152602001606081525090565b6001600160a01b0381168114613c4e57600080fd5b50565b60008060408385031215613c6457600080fd5b8235613c6f81613c39565b91506020830135613c7f81613c39565b809150509250929050565b600080600060608486031215613c9f57600080fd5b8335613caa81613c39565b92506020840135613cba81613c39565b91506040840135613cca81613c39565b809150509250925092565b60008060408385031215613ce857600080fd5b8235613cf381613c39565b946020939093013593505050565b600060208284031215613d1357600080fd5b813561121981613c39565b8060070b8114613c4e57600080fd5b60008060008060808587031215613d4357600080fd5b8435613d4e81613c39565b93506020850135613d5e81613c39565b92506040850135613d6e81613c39565b91506060850135613d7e81613d1e565b939692955090935050565b60008060408385031215613d9c57600080fd5b8235613da781613c39565b91506020830135613c7f81613d1e565b60005b83811015613dd2578181015183820152602001613dba565b83811115613de1576000848401525b50505050565b60008151808452613dff816020860160208601613db7565b601f01601f19169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015613eca5782840389528151604081518652868201519150808787015281511515818701528682015160606001600160a01b03808316828a015283850151935060a09250608083818b0152613e8c60e08b0186613de7565b928601518a8403603f1901858c0152929450613ea88584613de7565b9501511660c09890980197909752505098850198935090840190600101613e31565b5091979650505050505050565b60006101608251818552613eed82860182613de7565b91505060208301518482036020860152613f078282613de7565b9150506040830151613f2460408601826001600160a01b03169052565b5060608301518482036060860152613f3c8282613de7565b9150506080830151613f52608086018215159052565b5060a0830151613f6760a086018260070b9052565b5060c0830151613f7b60c086018215159052565b5060e083015184820360e0860152613f938282613e13565b61010085810151805163ffffffff9081168984015260208201516001600160a01b03166101208a015260408201511661014089015291935091505090949350505050565b600081518084526020808501945080840160005b83811015614047578151805163ffffffff168852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a09096019590820190600101613feb565b509495945050505050565b600081518084526020808501945080840160005b83811015614047578151805163ffffffff9081168952848201518116858a01526040808301518216908a01526060808301519091169089015260808082015115159089015260a0908101516001600160a01b03169088015260c09096019590820190600101614066565b600081518084526020808501945080840160005b83811015614047578151805163ffffffff9081168952848201518116858a0152604080830151909116908901526060808201516001600160a01b03908116918a01919091526080808301511515908a015260a091820151169088015260c090960195908201906001016140e4565b6000610120825181855261416882860182613ed7565b9150506020830151614186602086018267ffffffffffffffff169052565b50604083015161419a604086018215159052565b5060608301516141ae606086018215159052565b5060808301516141c2608086018215159052565b5060a083015184820360a08601526141da8282613fd7565b91505060c083015184820360c08601526141f48282614052565b91505060e083015184820360e086015261420e82826140d0565b91505061010080840151858303828701526142298382613de7565b9695505050505050565b6000815160c0845261424860c0850182614152565b9050602083015160070b602085015260408301516001600160a01b038082166040870152606085015160070b60608701526080850151915085830360808701526142928383613de7565b92508060a08601511660a087015250508091505092915050565b8281526040602082015260006111586040830184614233565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156142fe576142fe6142c5565b60405290565b6040805190810167ffffffffffffffff811182821017156142fe576142fe6142c5565b60405160a0810167ffffffffffffffff811182821017156142fe576142fe6142c5565b604051610120810167ffffffffffffffff811182821017156142fe576142fe6142c5565b60405160c0810167ffffffffffffffff811182821017156142fe576142fe6142c5565b604051601f8201601f1916810167ffffffffffffffff811182821017156143ba576143ba6142c5565b604052919050565b600067ffffffffffffffff8211156143dc576143dc6142c5565b5060051b60200190565b6000806000606084860312156143fb57600080fd5b833561440681613c39565b925060208481013561441781613c39565b9250604085013567ffffffffffffffff81111561443357600080fd5b8501601f8101871361444457600080fd5b8035614457614452826143c2565b614391565b81815260059190911b8201830190838101908983111561447657600080fd5b928401925b8284101561449d57833561448e81613d1e565b8252928401929084019061447b565b80955050505050509250925092565b63ffffffff81168114613c4e57600080fd5b60008082840360808112156144d257600080fd5b83356144dd81613c39565b92506060601f19820112156144f157600080fd5b506144fa6142db565b6020840135614508816144ac565b8152604084013561451881613c39565b6020820152606084013561452b816144ac565b6040820152919491935090915050565b8460070b81526080602082015260006145576080830186613fd7565b82810360408401526145698186614052565b9050828103606084015261457d81856140d0565b979650505050505050565b600081516040845261459d6040850182614152565b60209384015163ffffffff16949093019390935250919050565b8281526040602082015260006111586040830184614588565b67ffffffffffffffff81168114613c4e57600080fd5b600067ffffffffffffffff821115614600576146006142c5565b50601f01601f191660200190565b60008060006060848603121561462357600080fd5b833561462e81613c39565b925060208481013561463f816145d0565b925060408581013567ffffffffffffffff8082111561465d57600080fd5b818801915088601f83011261467157600080fd5b813561467f614452826143c2565b81815260059190911b8301850190858101908b83111561469e57600080fd5b8685015b83811015614712578035858111156146ba5760008081fd5b8601603f81018e136146cc5760008081fd5b888101356146dc614452826145e6565b8181528f8a8385010111156146f15760008081fd5b818a84018c83013760009181018b01919091528452509187019187016146a2565b50809750505050505050509250925092565b600081518084526020808501945080840160005b8381101561404757815160070b87529582019590820190600101614738565b83815267ffffffffffffffff831660208201526060604082015260006147806060830184614724565b95945050505050565b6000806020838503121561479c57600080fd5b823567ffffffffffffffff808211156147b457600080fd5b818501915085601f8301126147c857600080fd5b8135818111156147d757600080fd5b8660208260051b85010111156147ec57600080fd5b60209290920196919550909350505050565b828152608081016112196020830184805163ffffffff90811683526020808301516001600160a01b03169084015260409182015116910152565b60008060006060848603121561484d57600080fd5b833561485881613c39565b9250602084013561486881613c39565b91506040840135613cca816144ac565b8015158114613c4e57600080fd5b60008060006060848603121561489b57600080fd5b83356148a681613c39565b925060208401356148b681613c39565b91506040840135613cca81614878565b8281526040602082015260006111586040830184614152565b6000806000606084860312156148f457600080fd5b83356148ff81613c39565b9250602084013561490f81613c39565b929592945050506040919091013590565b60006020828403121561493257600080fd5b813561121981614878565b60008060006060848603121561495257600080fd5b833561495d81613c39565b9250602084013561496d81613c39565b91506040840135613cca81613d1e565b8051611b9b81613d1e565b60006020828403121561499a57600080fd5b815161121981613d1e565b6000602082840312156149b757600080fd5b5051919050565b600082516149d0818460208701613db7565b9190910192915050565b8051600381900b8114611b9b57600080fd5b6000602082840312156149fe57600080fd5b611219826149da565b634e487b7160e01b600052603260045260246000fd5b600181811c90821680614a3157607f821691505b60208210811415614a5257634e487b7160e01b600052602260045260246000fd5b50919050565b6020815260006112196020830184614233565b6001600160a01b0383168152608081016112196020830184805163ffffffff90811683526020808301516001600160a01b03169084015260409182015116910152565b606081526000614ac16060830186613fd7565b8281036020840152614ad38186614052565b9050828103604084015261422981856140d0565b6020815260006112196020830184614588565b67ffffffffffffffff831681526040602082015260006111586040830184614724565b600082601f830112614b2e57600080fd5b81356020614b3e614452836143c2565b82815260609283028501820192828201919087851115614b5d57600080fd5b8387015b85811015614bbf5781818a031215614b795760008081fd5b614b816142db565b8135614b8c81613c39565b815281860135614b9b81613c39565b81870152604082810135614bae81613d1e565b908201528452928401928101614b61565b5090979650505050505050565b6000614bda614452846143c2565b80848252602080830192508560051b850136811115614bf857600080fd5b855b81811015614d2d57803567ffffffffffffffff80821115614c1b5760008081fd5b818901915060608236031215614c315760008081fd5b614c396142db565b8235614c4481613c39565b81528286013582811115614c585760008081fd5b830136601f820112614c6a5760008081fd5b8035614c78614452826143c2565b81815260069190911b82018801908881019036831115614c985760008081fd5b928901925b82841015614cee5760408436031215614cb65760008081fd5b614cbe614304565b8435614cc981613c39565b8152848b0135614cd881613d1e565b818c015282526040939093019290890190614c9d565b848a01525060409150508381013583811115614d0a5760008081fd5b614d1636828701614b1d565b918301919091525087525050938201938201614bfa565b50919695505050505050565b8051611b9b81614878565b60008060408385031215614d5757600080fd5b8251614d6281613d1e565b6020840151909250613c7f81614878565b8051611b9b81613c39565b600060608284031215614d9057600080fd5b614d986142db565b90508151614da5816144ac565b81526020820151614db581613c39565b60208201526040820151614dc8816144ac565b604082015292915050565b60008060808385031215614de657600080fd5b82519150614df78460208501614d7e565b90509250929050565b606081016109628284805163ffffffff90811683526020808301516001600160a01b03169084015260409182015116910152565b60008060808385031215614e4757600080fd5b614e50836149da565b9150614df78460208501614d7e565b60008060408385031215614e7257600080fd5b614e7b836149da565b91506020830151613c7f81614878565b6020815260006112196020830184614152565b60008160070b677fffffffffffffff19811415614ecb57634e487b7160e01b600052601160045260246000fd5b60000392915050565b60008060408385031215614ee757600080fd5b614ef0836149da565b91506020830151613c7f81613c39565b606081526000614f136060830186613ed7565b905067ffffffffffffffff8416602083015263ffffffff83166040830152949350505050565b600082601f830112614f4a57600080fd5b8151614f58614452826145e6565b818152846020838601011115614f6d57600080fd5b611158826020830160208701613db7565b600082601f830112614f8f57600080fd5b81516020614f9f614452836143c2565b82815260059290921b84018101918181019086841115614fbe57600080fd5b8286015b848110156150d457805167ffffffffffffffff80821115614fe257600080fd5b908801906040601f19838c038101821315614ffc57600080fd5b615004614304565b888501518152828501518481111561501b57600080fd5b949094019360a0858e03830112156150335760008081fd5b61503b614327565b91508885015161504a81614878565b82528483015161505981613c39565b828a0152606085810151858111156150715760008081fd5b61507f8f8c838a0101614f39565b858501525060809350838601518581111561509a5760008081fd5b6150a88f8c838a0101614f39565b8285015250506150ba60a08601614d73565b928201929092528188015285525050918301918301614fc2565b509695505050505050565b600061016082840312156150f257600080fd5b6150fa61434a565b9050815167ffffffffffffffff8082111561511457600080fd5b61512085838601614f39565b8352602084015191508082111561513657600080fd5b61514285838601614f39565b602084015261515360408501614d73565b6040840152606084015191508082111561516c57600080fd5b61517885838601614f39565b606084015261518960808501614d39565b608084015261519a60a0850161497d565b60a08401526151ab60c08501614d39565b60c084015260e08401519150808211156151c457600080fd5b506151d184828501614f7e565b60e0830152506101006151e684828501614d7e565b9082015292915050565b8051611b9b816145d0565b600082601f83011261520c57600080fd5b8151602061521c614452836143c2565b82815260a0928302850182019282820191908785111561523b57600080fd5b8387015b85811015614bbf5781818a0312156152575760008081fd5b61525f614327565b815161526a816144ac565b81528186015161527981613c39565b8187015260408281015161528c81614878565b9082015260608281015161529f81614878565b908201526080828101516152b281613c39565b90820152845292840192810161523f565b600082601f8301126152d457600080fd5b815160206152e4614452836143c2565b82815260c0928302850182019282820191908785111561530357600080fd5b8387015b85811015614bbf5781818a03121561531f5760008081fd5b61532761436e565b8151615332816144ac565b815281860151615341816144ac565b81870152604082810151615354816144ac565b90820152606082810151615367816144ac565b9082015260808281015161537a81614878565b9082015260a08281015161538d81613c39565b908201528452928401928101615307565b600082601f8301126153af57600080fd5b815160206153bf614452836143c2565b82815260c092830285018201928282019190878511156153de57600080fd5b8387015b85811015614bbf5781818a0312156153fa5760008081fd5b61540261436e565b815161540d816144ac565b81528186015161541c816144ac565b8187015260408281015161542f816144ac565b9082015260608281015161544281613c39565b9082015260808281015161545581614878565b9082015260a08281015161546881613c39565b9082015284529284019281016153e2565b6000610120828403121561548c57600080fd5b61549461434a565b9050815167ffffffffffffffff808211156154ae57600080fd5b6154ba858386016150df565b83526154c8602085016151f0565b60208401526154d960408501614d39565b60408401526154ea60608501614d39565b60608401526154fb60808501614d39565b608084015260a084015191508082111561551457600080fd5b615520858386016151fb565b60a084015260c084015191508082111561553957600080fd5b615545858386016152c3565b60c084015260e084015191508082111561555e57600080fd5b61556a8583860161539e565b60e08401526101009150818401518181111561558557600080fd5b61559186828701614f39565b8385015250505092915050565b600080604083850312156155b157600080fd5b6155ba836149da565b9150602083015167ffffffffffffffff808211156155d757600080fd5b9084019060c082870312156155eb57600080fd5b6155f361436e565b82518281111561560257600080fd5b61560e88828601615479565b82525061561d6020840161497d565b602082015261562e60408401614d73565b604082015261563f6060840161497d565b606082015260808301518281111561565657600080fd5b61566288828601614f39565b60808301525061567460a08401614d73565b60a08201528093505050509250929050565b60006001600160a01b038086168352808516602084015250606060408301526147806060830184614724565b600080604083850312156156c557600080fd5b6156ce836149da565b9150602083015190509250929050565b600080600080608085870312156156f457600080fd5b6156fd856149da565b9350602085015167ffffffffffffffff8082111561571a57600080fd5b615726888389016151fb565b9450604087015191508082111561573c57600080fd5b615748888389016152c3565b9350606087015191508082111561575e57600080fd5b5061576b8782880161539e565b91505092959194509250565b6000806040838503121561578a57600080fd5b615793836149da565b9150602083015167ffffffffffffffff808211156157b057600080fd5b90840190604082870312156157c457600080fd5b6040516040810181811083821117156157df576157df6142c5565b6040528251828111156157f157600080fd5b6157fd88828601615479565b82525060208301519250615810836144ac565b8260208201528093505050509250929050565b6000606082016001600160a01b0386168352602067ffffffffffffffff8616818501526060604085015281855180845260808601915060808160051b870101935082870160005b8281101561589857607f19888703018452615886868351613de7565b9550928401929084019060010161586a565b50939998505050505050505050565b6000806000606084860312156158bc57600080fd5b6158c5846149da565b92506020808501516158d6816145d0565b604086015190935067ffffffffffffffff8111156158f357600080fd5b8501601f8101871361590457600080fd5b8051615912614452826143c2565b81815260059190911b8201830190838101908983111561593157600080fd5b928401925b8284101561449d57835161594981613d1e565b82529284019290840190615936565b60a08152600061596b60a0830188613ed7565b67ffffffffffffffff8716602084015263ffffffff8616604084015282810360608401526159998186613fd7565b905082810360808401526159ad8185614052565b98975050505050505050565b600081518084526020808501945080840160005b8381101561404757815180516001600160a01b03908116895284820151168489015260409081015160070b90880152606090960195908201906001016159cd565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b84811015615ad557898403603f19018652825180516001600160a01b0390811686528982015160608b880181905281519088018190526080880192918c01919086905b80821015615aa75783518051841686528e015160070b8e860152938c0193928d019260019190910190615a79565b5050505090880151858203868a015290615ac181836159b9565b978a01979550505091870191600101615a36565b50919998505050505050505050565b6020815260006112196020830184613ed7565b60008060408385031215615b0a57600080fd5b615b13836149da565b9150602083015167ffffffffffffffff811115615b2f57600080fd5b615b3b85828601615479565b915050925092905056fe90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aaa26469706673582212209b2868512f7ada058e50140bc7190fa533d71748a7da3f3bddc48212a1d566c664736f6c63430008090033", + "bytecode": "0x60c06040526009608081905268746f6b656e4e616d6560b81b60a09081526200002c9160019190620000cb565b5060408051808201909152600b8082526a1d1bdad95b94de5b589bdb60aa1b60209092019182526200006191600291620000cb565b50604080518082019091526004808252636d656d6f60e01b60209092019182526200008f91600391620000cb565b506103e860048190556005805463ffffffff1916909117905560086006556007805460ff19169055348015620000c457600080fd5b50620001ae565b828054620000d99062000171565b90600052602060002090601f016020900481019282620000fd576000855562000148565b82601f106200011857805160ff191683800117855562000148565b8280016001018555821562000148579182015b82811115620001485782518255916020019190600101906200012b565b50620001569291506200015a565b5090565b5b808211156200015657600081556001016200015b565b600181811c908216806200018657607f821691505b60208210811415620001a857634e487b7160e01b600052602260045260246000fd5b50919050565b615dfe80620001be6000396000f3fe6080604052600436106102dc5760003560e01c80638070905f11610184578063d85f74c1116100d6578063f2f38a741161008a578063f848fec411610064578063f848fec4146108b7578063f9e978bd146108d7578063fdc8321e146108f757600080fd5b8063f2f38a7414610849578063f4a01e5b14610877578063f7be34251461089757600080fd5b8063eee55ac8116100bb578063eee55ac8146107e9578063f25b120014610809578063f2c31ff41461082957600080fd5b8063d85f74c1146107b6578063d92ac248146107c957600080fd5b80639604ca6511610138578063af99c63311610112578063af99c63314610748578063c0b19b6d14610768578063d614cdb81461079657600080fd5b80639604ca65146106e8578063a345f7bd14610708578063a3ad5b551461072857600080fd5b80638ba74da0116101695780638ba74da01461067b5780638c99ef5d1461068e5780638f8d7f99146106c857600080fd5b80638070905f1461062c57806386f88d881461065b57600080fd5b80634cbdb37b1161023d5780635d2c5bad116101f15780636da6b1f0116101cb5780636da6b1f0146105cc5780637c41ad2c146105ec5780637d3e5da81461060c57600080fd5b80635d2c5bad1461054157806369837dc21461057e5780636a4dde21146105ac57600080fd5b8063593d6e8211610222578063593d6e82146104bc5780635a5e6c31146104dc5780635b9076b71461051157600080fd5b80634cbdb37b1461046e57806356af84031461049c57600080fd5b80632eecbca3116102945780633eed2c39116102795780633eed2c39146104195780634b5c6687146104395780634ba670351461044e57600080fd5b80632eecbca3146103d95780633b3bff0f146103f957600080fd5b806319db44b6116102c557806319db44b61461034e5780632b256ec81461038b5780632d73bb2e146103b957600080fd5b80630fd2601e146102e157806313c05dd814610319575b600080fd5b3480156102ed57600080fd5b506103016102fc3660046146bc565b610917565b60405160079190910b81526020015b60405180910390f35b34801561032557600080fd5b506103396103343660046146f4565b6109db565b60408051928352901515602083015201610310565b34801561035a57600080fd5b5061036e610369366004614a01565b610a59565b604080519283526001600160a01b03909116602083015201610310565b34801561039757600080fd5b506103ab6103a63660046146a0565b610add565b604051908152602001610310565b3480156103c557600080fd5b506103ab6103d43660046146bc565b610bc9565b3480156103e557600080fd5b506103016103f43660046146bc565b610c0e565b34801561040557600080fd5b506103ab6104143660046146a0565b610c45565b34801561042557600080fd5b506103396104343660046146a0565b610d1f565b61044c6104473660046146a0565b610d99565b005b34801561045a57600080fd5b506103ab61046936600461473e565b611191565b34801561047a57600080fd5b5061048e610489366004614959565b6111dd565b60405161031092919061583f565b3480156104a857600080fd5b506103ab6104b7366004614799565b611253565b3480156104c857600080fd5b506103ab6104d7366004614986565b61129d565b3480156104e857600080fd5b506104fc6104f73660046146f4565b61137a565b60408051928352602083019190915201610310565b34801561051d57600080fd5b5061053161052c3660046146a0565b6113eb565b604051610310949392919061589a565b34801561054d57600080fd5b5061056161055c3660046146a0565b61147d565b6040805160079390930b835260039190910b602083015201610310565b34801561058a57600080fd5b5061059e6105993660046146a0565b6114f8565b604051610310929190615826565b3480156105b857600080fd5b506103396105c73660046146bc565b61156d565b3480156105d857600080fd5b506103ab6105e736600461473e565b6115e4565b3480156105f857600080fd5b506103ab6106073660046146a0565b6115f2565b34801561061857600080fd5b506103ab6106273660046146bc565b611620565b34801561063857600080fd5b5061064c610647366004614a2c565b61162c565b60405161031093929190615871565b34801561066757600080fd5b506103396106763660046146a0565b6116b4565b61044c6106893660046146bc565b611725565b34801561069a57600080fd5b506106ae6106a93660046146a0565b611be1565b6040805160079390930b8352901515602083015201610310565b3480156106d457600080fd5b506103016106e33660046146bc565b611c5a565b3480156106f457600080fd5b506103ab610703366004614b3a565b611c90565b34801561071457600080fd5b506103ab6107233660046146a0565b611cc5565b34801561073457600080fd5b506106ae6107433660046146bc565b611d0b565b34801561075457600080fd5b506103016107633660046146bc565b611dfd565b34801561077457600080fd5b506107886107833660046146a0565b611e33565b6040516103109291906157ec565b3480156107a257600080fd5b506107886107b13660046146a0565b611f2a565b61044c6107c43660046146a0565b612034565b3480156107d557600080fd5b506103ab6107e436600461491a565b612412565b3480156107f557600080fd5b506103ab610804366004614986565b61241f565b34801561081557600080fd5b506103ab61082436600461485c565b6124b2565b34801561083557600080fd5b506106ae6108443660046146bc565b6124bf565b34801561085557600080fd5b506108696108643660046146a0565b61259a565b604051610310929190615858565b34801561088357600080fd5b506103ab6108923660046146bc565b61260f565b3480156108a357600080fd5b506103ab6108b23660046146a0565b61261b565b3480156108c357600080fd5b506103ab6108d23660046148da565b6126fe565b3480156108e357600080fd5b5061044c6108f2366004614baa565b61270b565b34801561090357600080fd5b506103ab61091236600461489b565b612758565b604051638f8d7f9960e01b81526001600160a01b038084166004830152821660248201526000903090638f8d7f99906044015b602060405180830381600087803b15801561096457600080fd5b505af1158015610978573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099c9190615016565b604051600782900b8152909150600080516020615da98339815191529060200160405180910390a1600781900b6016146109d557600080fd5b92915050565b6000806109e9858585612959565b6040518281529193509150600080516020615da98339815191529060200160405180910390a160168214610a1c57600080fd5b60405181151581527e1c2e72360171244b3bb8cc8ddd767820edf37138ad6f129fb3574b407c307d906020015b60405180910390a1935093915050565b600080610a668484612a58565b6040518281529193509150600080516020615da98339815191529060200160405180910390a160168214610a9957600080fd5b6040516001600160a01b03821681527fc2c78c7c31baf14949e75c51df12be56edb9af523cf82839c2869bbcf13b3ecb906020015b60405180910390a19250929050565b604051631f106b4b60e21b81526001600160a01b03821660048201526000903090637c41ad2c90602401602060405180830381600087803b158015610b2157600080fd5b505af1158015610b35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b599190614bc6565b9050600080516020615da983398151915281604051610b7a91815260200190565b60405180910390a160168114610b8f57600080fd5b604051600181527f0c9c765845f4d139956bb8fc8decb2eec6093c9c608b809641b16054b29f0e13906020015b60405180910390a1919050565b6000610bd58383612b38565b60070b9050600080516020615da983398151915281604051610bf991815260200190565b60405180910390a1601681146109d557600080fd5b60405163af99c63360e01b81526001600160a01b03808416600483015282166024820152600090309063af99c6339060440161094a565b6040516001600160a01b03821660248201526000908190819061016790633b3bff0f60e01b906044015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610cad91906155c9565b6000604051808303816000865af19150503d8060008114610cea576040519150601f19603f3d011682016040523d82523d6000602084013e610cef565b606091505b509150915081610d00576015610d14565b80806020019051810190610d149190614c0a565b60030b949350505050565b600080610d2b83612b87565b6040518281529193509150600080516020615da98339815191529060200160405180910390a160168214610d5e57600080fd5b60405181151581527f6b7f3306751292f85ab4161ee2b0ac16dfc8ded13e6446ce6bd859d0a2f4c78e906020015b60405180910390a1915091565b60408051600480825260a08201909252600091816020015b610db9613d8e565b815260200190600190039081610db1579050509050610dec60006006600160405180602001604052806000815250612c84565b81600081518110610e0d57634e487b7160e01b600052603260045260246000fd5b6020026020010181905250610e3360018060405180602001604052806000815250612cbb565b81600181518110610e5457634e487b7160e01b600052603260045260246000fd5b6020026020010181905250610e7b6002600160405180602001604052806000815250612cbb565b81600281518110610e9c57634e487b7160e01b600052603260045260246000fd5b6020026020010181905250610ec36003600160405180602001604052806000815250612cbb565b81600381518110610ee457634e487b7160e01b600052603260045260246000fd5b602002602001018190525060006040518060600160405280600063ffffffff168152602001846001600160a01b03168152602001627a120063ffffffff168152509050600060405180610120016040528060018054610f4290615cc8565b80601f0160208091040260200160405190810160405280929190818152602001828054610f6e90615cc8565b8015610fbb5780601f10610f9057610100808354040283529160200191610fbb565b820191906000526020600020905b815481529060010190602001808311610f9e57829003601f168201915b5050505050815260200160028054610fd290615cc8565b80601f0160208091040260200160405190810160405280929190818152602001828054610ffe90615cc8565b801561104b5780601f106110205761010080835404028352916020019161104b565b820191906000526020600020905b81548152906001019060200180831161102e57829003601f168201915b50505050508152602001856001600160a01b031681526020016003805461107190615cc8565b80601f016020809104026020016040519081016040528092919081815260200182805461109d90615cc8565b80156110ea5780601f106110bf576101008083540402835291602001916110ea565b820191906000526020600020905b8154815290600101906020018083116110cd57829003601f168201915b50505091835250506001602082015260055463ffffffff16604082015260075460ff16151560608201526080810185905260a001839052600454600654919250600091829161113b91859190612cf0565b90925090506016821461114d57600080fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050565b600061119f85858585612e1e565b9050600080516020615da9833981519152816040516111c091815260200190565b60405180910390a1601681146111d557600080fd5b949350505050565b60006111e7613deb565b6111f18484612f2e565b6040518281529193509150600080516020615da98339815191529060200160405180910390a16016821461122457600080fd5b7fa516f81c528634d0fc1e993bba1d227231b4bd6d1beb72d33b056a6199c0f98881604051610ace91906159b7565b6000611260848484613021565b9050600080516020615da98339815191528160405161128191815260200190565b60405180910390a16016811461129657600080fd5b9392505050565b60008060006101676001600160a01b031663593d6e8260e01b86866040516024016112c992919061561a565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161130791906155c9565b6000604051808303816000865af19150503d8060008114611344576040519150601f19603f3d011682016040523d82523d6000602084013e611349565b606091505b50915091508161135a57601561136e565b8080602001905181019061136e9190614c0a565b60030b95945050505050565b600080611388858585613101565b6040518281529193509150600080516020615da98339815191529060200160405180910390a1601682146113bb57600080fd5b6040518181527f25b6684a7e8fe1b676e9c39c8dd65034fbafea906d3bdfd97bf748b7b55e14c890602001610a49565b600060608060606113fb856131ed565b604051600785900b815293975091955093509150600080516020615da98339815191529060200160405180910390a1600784900b60161461143b57600080fd5b7f2efc8334b040613a552197fe34283d6ca2909c8ffae393e128424931f20c69b383838360405161146e939291906156e0565b60405180910390a19193509193565b600080611489836132ed565b604051600783900b81529193509150600080516020615da98339815191529060200160405180910390a1600782900b6016146114c457600080fd5b604051600382900b81527f182137409609594f2b12128230091c673507ea4cab315d59415d5e3f8c301ad590602001610d8c565b6000611502613e26565b61150b836133ca565b6040518281529193509150600080516020615da98339815191529060200160405180910390a16016821461153e57600080fd5b7f476a9a9b28e2717d55288b2ae3c48a72aac52b11f8bd855017c9d41d9fc1896481604051610d8c919061591b565b60008061157a84846134b3565b60405160079290920b80835293509150600080516020615da98339815191529060200160405180910390a1601682146115b257600080fd5b60405181151581527f59800d968fcce138300a0019410b4b75041610d65b3cdc5f31656b03ed14912e90602001610ace565b600061119f85858585613504565b6040516001600160a01b03821660248201526000908190819061016790631f106b4b60e21b90604401610c6f565b6000610bd58383613565565b600080606061163c8686866135b4565b6040518381529295509093509150600080516020615da98339815191529060200160405180910390a16016831461167257600080fd5b7feff23992f47b3c101679f8b4dc9d3e242c903909dba4a453f2b2341ad463b0e282826040516116a39291906159dd565b60405180910390a193509350939050565b6000806116c0836136b2565b6040518281529193509150600080516020615da98339815191529060200160405180910390a1601682146116f357600080fd5b60405181151581527f9ee19e13dfa1ba8db2502e15ff56dbecdeb0e0473323fb195473ce648030a2cd90602001610d8c565b604080516001808252818301909252600091816020015b611744613d8e565b81526020019060019003908161173c579050509050611776600080600160405180602001604052806000815250612c84565b8160008151811061179757634e487b7160e01b600052603260045260246000fd5b602002602001018190525060006040518060600160405280600063ffffffff168152602001856001600160a01b03168152602001627a120063ffffffff1681525090506000604051806101200160405280600180546117f590615cc8565b80601f016020809104026020016040519081016040528092919081815260200182805461182190615cc8565b801561186e5780601f106118435761010080835404028352916020019161186e565b820191906000526020600020905b81548152906001019060200180831161185157829003601f168201915b505050505081526020016002805461188590615cc8565b80601f01602080910402602001604051908101604052809291908181526020018280546118b190615cc8565b80156118fe5780601f106118d3576101008083540402835291602001916118fe565b820191906000526020600020905b8154815290600101906020018083116118e157829003601f168201915b50505050508152602001866001600160a01b031681526020016003805461192490615cc8565b80601f016020809104026020016040519081016040528092919081815260200182805461195090615cc8565b801561199d5780601f106119725761010080835404028352916020019161199d565b820191906000526020600020905b81548152906001019060200180831161198057829003601f168201915b505050918352505060016020820181905260055463ffffffff166040808401919091526000606084018190526080840188905260a09093018690528051828152808201909152929350909190816020015b6040805160a0810182526000808252602080830182905292820181905260608201819052608082015282526000199092019101816119ee5750506040805160a081018252600181526001600160a01b03888116602083015260009282018390526060820183905289166080820152825192935091839190611a7f57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152604080516001808252818301909252600091816020015b6040805160c08101825260008082526020808301829052928201819052606082018190526080820181905260a08201528252600019909201910181611aa15750506040805160c0810182526004815260056020820152600a91810191909152601e60608201526000608082018190526001600160a01b038a1660a083015282519293509091839190611b4357634e487b7160e01b600052603260045260246000fd5b6020026020010181905250600080611b628560045460065487876136fb565b91509150600080516020615da983398151915282604051611b8591815260200190565b60405180910390a160168214611b9a57600080fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050505050565b600080611bed8361382f565b604051600783900b81529193509150600080516020615da98339815191529060200160405180910390a1600782900b601614611c2857600080fd5b60405181151581527f5080c42cc33acbcea410fa6eaa925bd878674825501981184fdd53749f8478a890602001610d8c565b6040516001600160a01b038381166024830152821660448201526000908190819061016790638f8d7f9960e01b906064016112c9565b6000611ca4611c9f8385615b33565b613878565b9050600080516020615da983398151915281604051610bf991815260200190565b6000611cd0826138a2565b9050600080516020615da983398151915281604051611cf191815260200190565b60405180910390a160168114611d0657600080fd5b919050565b604051633cb0c7fd60e21b81526001600160a01b038084166004830152821660248201526000908190309063f2c31ff4906044016040805180830381600087803b158015611d5857600080fd5b505af1158015611d6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d909190615032565b604051600783900b81529193509150600080516020615da98339815191529060200160405180910390a1600782900b601614611dcb57600080fd5b60405181151581527fd24dda6928587354b65aa1a18c2eaf249bef7e5bafd2a71fac71d286f76f957f90602001610ace565b6040516001600160a01b03838116602483015282166044820152600090819081906101679063af99c63360e01b906064016112c9565b60408051606081018252600080825260208201819052918101829052604051631ac299b760e31b81526001600160a01b0384166004820152309063d614cdb890602401608060405180830381600087803b158015611e9057600080fd5b505af1158015611ea4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec89190614bde565b6040518281529193509150600080516020615da98339815191529060200160405180910390a160168214611efb57600080fd5b7fa0a16bf9db2c17796faeca5af5aaeef8523f9d4c350c512cb00062ad89604f8881604051610d8c91906158e7565b604080516060810182526000808252602080830182905282840182905283516001600160a01b038616602480830191909152855180830390910181526044909101855290810180516001600160e01b0316631ac299b760e31b179052925190928391829161016791611f9c91906155c9565b6000604051808303816000865af19150503d8060008114611fd9576040519150601f19603f3d011682016040523d82523d6000602084013e611fde565b606091505b50604080516060810182526000808252602082018190529181019190915291935091508261200e57601581612022565b818060200190518101906120229190614d38565b60039190910b97909650945050505050565b60408051600580825260c08201909252600091816020015b612054613d8e565b81526020019060019003908161204c57905050905061208760006006600160405180602001604052806000815250612c84565b816000815181106120a857634e487b7160e01b600052603260045260246000fd5b60200260200101819052506120ce60018060405180602001604052806000815250612cbb565b816001815181106120ef57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506121166002600160405180602001604052806000815250612cbb565b8160028151811061213757634e487b7160e01b600052603260045260246000fd5b602002602001018190525061215e6004600160405180602001604052806000815250612cbb565b8160038151811061217f57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506121a66003600160405180602001604052806000815250612cbb565b816004815181106121c757634e487b7160e01b600052603260045260246000fd5b602002602001018190525060006040518060600160405280600063ffffffff168152602001846001600160a01b03168152602001627a120063ffffffff16815250905060006040518061012001604052806001805461222590615cc8565b80601f016020809104026020016040519081016040528092919081815260200182805461225190615cc8565b801561229e5780601f106122735761010080835404028352916020019161229e565b820191906000526020600020905b81548152906001019060200180831161228157829003601f168201915b50505050508152602001600280546122b590615cc8565b80601f01602080910402602001604051908101604052809291908181526020018280546122e190615cc8565b801561232e5780601f106123035761010080835404028352916020019161232e565b820191906000526020600020905b81548152906001019060200180831161231157829003601f168201915b50505050508152602001856001600160a01b031681526020016003805461235490615cc8565b80601f016020809104026020016040519081016040528092919081815260200182805461238090615cc8565b80156123cd5780601f106123a2576101008083540402835291602001916123cd565b820191906000526020600020905b8154815290600101906020018083116123b057829003601f168201915b50505091835250506001602082015260055463ffffffff16604082015260075460ff16151560608201526080810185905260a001839052905060008061113b836138e9565b60006112608484846139d3565b6040517f593d6e82000000000000000000000000000000000000000000000000000000008152600090309063593d6e8290612460908690869060040161561a565b602060405180830381600087803b15801561247a57600080fd5b505af115801561248e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca49190614bc6565b6000611260848484613a2e565b6040516001600160a01b0383811660248301528216604482015260009081908190819061016790633cb0c7fd60e21b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161253191906155c9565b6000604051808303816000865af19150503d806000811461256e576040519150601f19603f3d011682016040523d82523d6000602084013e612573565b606091505b5091509150816125865760156000612022565b808060200190518101906120229190614ce4565b60006125a4613e46565b6125ad83613a85565b6040518281529193509150600080516020615da98339815191529060200160405180910390a1601682146125e057600080fd5b7f528c7dcea75f0c9e110a038e50647cd6a70ac06d331399b77dd9a80f903ebc1681604051610d8c91906159ca565b6000611ca48383613b6e565b604051633b3bff0f60e01b81526001600160a01b03821660048201526000903090633b3bff0f90602401602060405180830381600087803b15801561265f57600080fd5b505af1158015612673573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126979190614bc6565b9050600080516020615da9833981519152816040516126b891815260200190565b60405180910390a1601681146126cd57600080fd5b604051600181527f319ab7084208e4afa38c6e6ff7aea9587439f2e4700746f4c7d425fea17426d290602001610bbc565b6000611260848484613bbd565b6007805460ff191682151590811790915560405160ff909116151581527f457c3a16a0ebdc38e3675609957ca3fcc4490e220bd15d85d34f58e2e145cb089060200160405180910390a150565b6040805160008082526020820190925281908161279d565b60408051606081018252600080825260208083018290529282015282526000199092019101816127705790505b50905060006040518060400160405280336001600160a01b03168152602001856127c690615d03565b600790810b9091526040805180820182526001600160a01b038a1681529187900b602083015280516002808252606082019092529293509091600091816020015b6040805180820190915260008082526020820152815260200190600190039081612807579050509050828160008151811061285257634e487b7160e01b600052603260045260246000fd5b6020026020010181905250818160018151811061287f57634e487b7160e01b600052603260045260246000fd5b602090810291909101810191909152604080516060810182526001600160a01b038a16815291820183905281810186905280516001808252818301909252600091816020015b6128f2604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816128c5579050509050818160008151811061292957634e487b7160e01b600052603260045260246000fd5b602002602001018190525061293d81613878565b96506016871461294c57600080fd5b5050505050509392505050565b604080516001600160a01b0385811660248301528481166044830152831660648083019190915282518083039091018152608490910182526020810180516001600160e01b03167ff49f40db000000000000000000000000000000000000000000000000000000001790529051600091829182918291610167916129dc916155c9565b6000604051808303816000865af19150503d8060008114612a19576040519150601f19603f3d011682016040523d82523d6000602084013e612a1e565b606091505b509150915081612a315760156000612a45565b80806020019051810190612a459190614ce4565b60039190910b9890975095505050505050565b604080516001600160a01b0384166024820152604480820184905282518083039091018152606490910182526020810180516001600160e01b03167f098f236600000000000000000000000000000000000000000000000000000000179052905160009182918291829161016791612acf916155c9565b6000604051808303816000865af19150503d8060008114612b0c576040519150601f19603f3d011682016040523d82523d6000602084013e612b11565b606091505b509150915081612b245760156000612022565b808060200190518101906120229190614c24565b6040516001600160a01b0383811660248301528216604482015260009081908190610167907f52f9138700000000000000000000000000000000000000000000000000000000906064016112c9565b6040516001600160a01b0382166024820152600090819081908190610167907fa7daa18d00000000000000000000000000000000000000000000000000000000906044015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612c0a91906155c9565b6000604051808303816000865af19150503d8060008114612c47576040519150601f19603f3d011682016040523d82523d6000602084013e612c4c565b606091505b509150915081612c5f5760156000612c73565b80806020019051810190612c739190614ce4565b60039190910b969095509350505050565b612c8c613d8e565b6040518060400160405280612ca18787613c13565b8152602001612cb08585613c2c565b905295945050505050565b612cc3613d8e565b6040518060400160405280612cd786613cfc565b8152602001612ce68585613c2c565b9052949350505050565b600080848061010001516000015163ffffffff166000148015612d2057506101008101516040015163ffffffff16155b15612d36576101008101516276a7006040909101525b6000806101676001600160a01b031634637812a04b60e01b8a8a8a604051602401612d6393929190615941565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612da191906155c9565b60006040518083038185875af1925050503d8060008114612dde576040519150601f19603f3d011682016040523d82523d6000602084013e612de3565b606091505b509150915081612df65760156000612e0a565b80806020019051810190612e0a9190614c24565b60039190910b999098509650505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b608482015260009081908190610167907feca36917000000000000000000000000000000000000000000000000000000009060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612eb991906155c9565b6000604051808303816000865af19150503d8060008114612ef6576040519150601f19603f3d011682016040523d82523d6000602084013e612efb565b606091505b509150915081612f0c576015612f20565b80806020019051810190612f209190614c0a565b60030b979650505050505050565b6000612f38613deb565b604080516001600160a01b0386166024820152600785900b60448083019190915282518083039091018152606490910182526020810180516001600160e01b03167f287e1da8000000000000000000000000000000000000000000000000000000001790529051600091829161016791612fb1916155c9565b6000604051808303816000865af19150503d8060008114612fee576040519150601f19603f3d011682016040523d82523d6000602084013e612ff3565b606091505b5091509150613000613deb565b8261300d57601581612a45565b81806020019051810190612a459190614e0a565b60008060006101676001600160a01b031663f7f38e2660e01b87878760405160240161304f939291906155e5565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161308d91906155c9565b6000604051808303816000865af19150503d80600081146130ca576040519150601f19603f3d011682016040523d82523d6000602084013e6130cf565b606091505b5091509150816130e05760156130f4565b808060200190518101906130f49190614c0a565b60030b9695505050505050565b604080516001600160a01b0385811660248301528481166044830152831660648083019190915282518083039091018152608490910182526020810180516001600160e01b03167f927da10500000000000000000000000000000000000000000000000000000000179052905160009182918291829161016791613184916155c9565b6000604051808303816000865af19150503d80600081146131c1576040519150601f19603f3d011682016040523d82523d6000602084013e6131c6565b606091505b5091509150816131d95760156000612a45565b80806020019051810190612a459190614f39565b604080516001600160a01b03831660248083019190915282518083039091018152604490910182526020810180516001600160e01b03167fae7611a0000000000000000000000000000000000000000000000000000000001790529051600091606091829182918591829161016791613265916155c9565b6000604051808303816000865af19150503d80600081146132a2576040519150601f19603f3d011682016040523d82523d6000602084013e6132a7565b606091505b50915091506060806060846132c05760158383836132d4565b838060200190518101906132d49190614c4f565b60039390930b9d919c509a509098509650505050505050565b604080516001600160a01b03831660248083019190915282518083039091018152604490910182526020810180516001600160e01b03167f93272baf00000000000000000000000000000000000000000000000000000000179052905160009182918291829161016791613360916155c9565b6000604051808303816000865af19150503d806000811461339d576040519150601f19603f3d011682016040523d82523d6000602084013e6133a2565b606091505b5091509150816133b6576015600019612c73565b80806020019051810190612c739190614d0f565b60006133d4613e26565b604080516001600160a01b03851660248083019190915282518083039091018152604490910182526020810180516001600160e01b03167f3f28a19b000000000000000000000000000000000000000000000000000000001790529051600091829161016791613443916155c9565b6000604051808303816000865af19150503d8060008114613480576040519150601f19603f3d011682016040523d82523d6000602084013e613485565b606091505b5091509150613492613e26565b8261349f57601581612022565b818060200190518101906120229190614d62565b6040516001600160a01b03838116602483015282166044820152600090819081908190610167907f46de0fb100000000000000000000000000000000000000000000000000000000906064016124f3565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b608482015260009081908190610167907f5cfc9011000000000000000000000000000000000000000000000000000000009060a401612e7b565b6040516001600160a01b0383811660248301528216604482015260009081908190610167907f5b8f858400000000000000000000000000000000000000000000000000000000906064016112c9565b60008060606000806101676001600160a01b031663278e0b8860e01b8989896040516024016135e59392919061565d565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161362391906155c9565b6000604051808303816000865af19150503d8060008114613660576040519150601f19603f3d011682016040523d82523d6000602084013e613665565b606091505b50915091508161368857604080516000808252602082019092526015919061369c565b8080602001905181019061369c9190614f64565b60039290920b9a90995090975095505050505050565b6040516001600160a01b0382166024820152600090819081908190610167907f335e04c10000000000000000000000000000000000000000000000000000000090604401612bcc565b600080868061010001516000015163ffffffff16600014801561372b57506101008101516040015163ffffffff16155b15613741576101008101516276a7006040909101525b6000806101676001600160a01b031634634c381ae760e01b8c8c8c8c8c604051602401613772959493929190615966565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516137b091906155c9565b60006040518083038185875af1925050503d80600081146137ed576040519150601f19603f3d011682016040523d82523d6000602084013e6137f2565b606091505b5091509150816138055760156000613819565b808060200190518101906138199190614c24565b60039190910b9b909a5098505050505050505050565b6040516001600160a01b0382166024820152600090819081908190610167907f19f373610000000000000000000000000000000000000000000000000000000090604401612bcc565b60008060006101676001600160a01b031663189a554c60e01b85604051602401610c6f9190615719565b6040516001600160a01b038216602482015260009081908190610167907ff069f7120000000000000000000000000000000000000000000000000000000090604401610c6f565b600080828061010001516000015163ffffffff16600014801561391957506101008101516040015163ffffffff16155b1561392f576101008101516276a7006040909101525b6000806101676001600160a01b031634639dc711e060e01b88604051602401613958919061592e565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161399691906155c9565b60006040518083038185875af1925050503d8060008114612b0c576040519150601f19603f3d011682016040523d82523d6000602084013e612b11565b6040516001600160a01b0384811660248301528316604482015263ffffffff8216606482015260009081908190610167907f9790686d000000000000000000000000000000000000000000000000000000009060840161304f565b6040516001600160a01b03848116602483015283166044820152811515606482015260009081908190610167907f367605ca000000000000000000000000000000000000000000000000000000009060840161304f565b6000613a8f613e46565b604080516001600160a01b03851660248083019190915282518083039091018152604490910182526020810180516001600160e01b03167f1f69565f000000000000000000000000000000000000000000000000000000001790529051600091829161016791613afe916155c9565b6000604051808303816000865af19150503d8060008114613b3b576040519150601f19603f3d011682016040523d82523d6000602084013e613b40565b606091505b5091509150613b4d613e46565b82613b5a57601581612022565b818060200190518101906120229190614eed565b6040516001600160a01b0383811660248301528216604482015260009081908190610167907f49146bde00000000000000000000000000000000000000000000000000000000906064016112c9565b6040516001600160a01b038481166024830152831660448201526064810182905260009081908190610167907fe1f21c67000000000000000000000000000000000000000000000000000000009060840161304f565b6000600160ff84161b9050600160ff83161b8117611296565b613c726040518060a0016040528060001515815260200160006001600160a01b03168152602001606081526020016060815260200160006001600160a01b031681525090565b8260ff1660011415613c8757600181526109d5565b8260ff1660021415613ca9576000546001600160a01b031660208201526109d5565b8260ff1660031415613cc157604081018290526109d5565b8260ff1660041415613cd957606081018290526109d5565b8260ff16600514156109d5576000546001600160a01b0316608082015292915050565b600060ff8216613d0e57506001919050565b8160ff1660011415613d2257506002919050565b8160ff1660021415613d3657506004919050565b8160ff1660031415613d4a57506008919050565b8160ff1660041415613d5e57506010919050565b8160ff1660051415613d7257506020919050565b8160ff1660061415613d8657506040919050565b506000919050565b604051806040016040528060008152602001613de66040518060a0016040528060001515815260200160006001600160a01b03168152602001606081526020016060815260200160006001600160a01b031681525090565b905290565b6040518060c00160405280613dfe613e46565b8152600060208201819052604082018190526060808301829052608083015260a09091015290565b6040518060400160405280613e39613e46565b8152600060209091015290565b60408051610240810182526060610120820181815261014083018290526000610160840181905261018084018390526101a084018190526101c084018190526101e0840181905261020084018390528451928301855280835260208301819052938201939093526102208201529081908152602001600067ffffffffffffffff168152602001600015158152602001600015158152602001600015158152602001606081526020016060815260200160608152602001606081525090565b8051611d0681615d4b565b600082601f830112613f1f578081fd5b81516020613f34613f2f83615ae7565b615ab6565b8281528181019085830160a080860288018501891015613f52578687fd5b865b86811015613fdb5781838b031215613f6a578788fd5b613f72615a00565b8351613f7d81615d80565b815283870151613f8c81615d4b565b81880152604084810151613f9f81615d63565b90820152606084810151613fb281615d63565b90820152608084810151613fc581615d4b565b9082015285529385019391810191600101613f54565b509198975050505050505050565b600082601f830112613ff9578081fd5b81516020614009613f2f83615ae7565b8281528181019085830160c080860288018501891015614027578687fd5b865b86811015613fdb5781838b03121561403f578788fd5b614047615a29565b835161405281615d80565b81528387015161406181615d80565b8188015260408481015161407481615d80565b9082015260608481015161408781615d80565b9082015260808481015161409a81615d63565b9082015260a0848101516140ad81615d4b565b9082015285529385019391810191600101614029565b600082601f8301126140d3578081fd5b813560206140e3613f2f83615ae7565b82815281810190858301606080860288018501891015614101578687fd5b865b86811015613fdb5781838b031215614119578788fd5b614121615a4c565b833561412c81615d4b565b81528387013561413b81615d4b565b8188015260408481013561414e81615d71565b9082015285529385019391810191600101614103565b600082601f830112614174578081fd5b81516020614184613f2f83615ae7565b8281528181019085830160c0808602880185018910156141a2578687fd5b865b86811015613fdb5781838b0312156141ba578788fd5b6141c2615a29565b83516141cd81615d80565b8152838701516141dc81615d80565b818801526040848101516141ef81615d80565b9082015260608481015161420281615d4b565b9082015260808481015161421581615d63565b9082015260a08481015161422881615d4b565b90820152855293850193918101916001016141a4565b600082601f83011261424e578081fd5b8151602061425e613f2f83615ae7565b80838252828201915082860187848660051b890101111561427d578586fd5b855b8581101561438a57815167ffffffffffffffff8082111561429e578889fd5b90890190601f196040838d03820112156142b657898afd5b6142be615a6f565b8884015181526040840151838111156142d5578b8cfd5b939093019260a0848e03830112156142eb578a8bfd5b6142f3615a00565b91508884015161430281615d63565b825261431060408501613f04565b89830152606084015183811115614325578b8cfd5b6143338e8b838801016143a2565b60408401525060808401518381111561434a578b8cfd5b6143588e8b838801016143a2565b60608401525061436a60a08501613f04565b60808301528089019190915286525050928401929084019060010161427f565b5090979650505050505050565b8051611d0681615d63565b600082601f8301126143b2578081fd5b81516143c0613f2f82615b0b565b8181528460208386010111156143d4578283fd5b6111d5826020830160208701615c98565b8051600381900b8114611d0657600080fd5b8051611d0681615d71565b600060608284031215614413578081fd5b61441b615a4c565b9050815161442881615d80565b8152602082015161443881615d4b565b6020820152604082015161444b81615d80565b604082015292915050565b60006101608284031215614468578081fd5b614470615a92565b9050815167ffffffffffffffff8082111561448a57600080fd5b614496858386016143a2565b835260208401519150808211156144ac57600080fd5b6144b8858386016143a2565b60208401526144c960408501613f04565b604084015260608401519150808211156144e257600080fd5b6144ee858386016143a2565b60608401526144ff60808501614397565b608084015261451060a0850161468a565b60a084015261452160c08501614397565b60c084015260e084015191508082111561453a57600080fd5b506145478482850161423e565b60e08301525061010061455c84828501614402565b9082015292915050565b60006101208284031215614578578081fd5b614580615a92565b9050815167ffffffffffffffff8082111561459a57600080fd5b6145a685838601614456565b83526145b460208501614695565b60208401526145c560408501614397565b60408401526145d660608501614397565b60608401526145e760808501614397565b608084015260a084015191508082111561460057600080fd5b61460c85838601613f0f565b60a084015260c084015191508082111561462557600080fd5b61463185838601613fe9565b60c084015260e084015191508082111561464a57600080fd5b61465685838601614164565b60e08401526101009150818401518181111561467157600080fd5b61467d868287016143a2565b8385015250505092915050565b8051611d0681615d80565b8051611d0681615d92565b6000602082840312156146b1578081fd5b813561129681615d4b565b600080604083850312156146ce578081fd5b82356146d981615d4b565b915060208301356146e981615d4b565b809150509250929050565b600080600060608486031215614708578081fd5b833561471381615d4b565b9250602084013561472381615d4b565b9150604084013561473381615d4b565b809150509250925092565b60008060008060808587031215614753578182fd5b843561475e81615d4b565b9350602085013561476e81615d4b565b9250604085013561477e81615d4b565b9150606085013561478e81615d71565b939692955090935050565b6000806000606084860312156147ad578081fd5b83356147b881615d4b565b92506020848101356147c981615d4b565b9250604085013567ffffffffffffffff8111156147e4578283fd5b8501601f810187136147f4578283fd5b8035614802613f2f82615ae7565b8082825284820191508484018a868560051b8701011115614821578687fd5b8694505b8385101561484c57803561483881615d71565b835260019490940193918501918501614825565b5080955050505050509250925092565b600080600060608486031215614870578081fd5b833561487b81615d4b565b9250602084013561488b81615d4b565b9150604084013561473381615d63565b6000806000606084860312156148af578081fd5b83356148ba81615d4b565b925060208401356148ca81615d4b565b9150604084013561473381615d71565b6000806000606084860312156148ee578081fd5b83356148f981615d4b565b9250602084013561490981615d4b565b929592945050506040919091013590565b60008060006060848603121561492e578081fd5b833561493981615d4b565b9250602084013561494981615d4b565b9150604084013561473381615d80565b6000806040838503121561496b578182fd5b823561497681615d4b565b915060208301356146e981615d71565b6000808284036080811215614999578283fd5b83356149a481615d4b565b92506060601f19820112156149b7578182fd5b506149c0615a4c565b60208401356149ce81615d80565b815260408401356149de81615d4b565b602082015260608401356149f181615d80565b6040820152919491935090915050565b60008060408385031215614a13578182fd5b8235614a1e81615d4b565b946020939093013593505050565b600080600060608486031215614a40578081fd5b8335614a4b81615d4b565b9250602084810135614a5c81615d92565b9250604085013567ffffffffffffffff80821115614a78578384fd5b818701915087601f830112614a8b578384fd5b8135614a99613f2f82615ae7565b8082825285820191508585018b878560051b8801011115614ab8578788fd5b875b84811015614b2857813586811115614ad057898afd5b8701603f81018e13614ae057898afd5b88810135614af0613f2f82615b0b565b8181528f6040838501011115614b04578b8cfd5b81604084018c8301379081018a018b90528552509287019290870190600101614aba565b50508096505050505050509250925092565b60008060208385031215614b4c578182fd5b823567ffffffffffffffff80821115614b63578384fd5b818501915085601f830112614b76578384fd5b813581811115614b84578485fd5b8660208260051b8501011115614b98578485fd5b60209290920196919550909350505050565b600060208284031215614bbb578081fd5b813561129681615d63565b600060208284031215614bd7578081fd5b5051919050565b60008060808385031215614bf0578182fd5b82519150614c018460208501614402565b90509250929050565b600060208284031215614c1b578081fd5b611296826143e5565b60008060408385031215614c36578182fd5b614c3f836143e5565b915060208301516146e981615d4b565b60008060008060808587031215614c64578182fd5b614c6d856143e5565b9350602085015167ffffffffffffffff80821115614c89578384fd5b614c9588838901613f0f565b94506040870151915080821115614caa578384fd5b614cb688838901613fe9565b93506060870151915080821115614ccb578283fd5b50614cd887828801614164565b91505092959194509250565b60008060408385031215614cf6578182fd5b614cff836143e5565b915060208301516146e981615d63565b60008060408385031215614d21578182fd5b614d2a836143e5565b9150614c01602084016143e5565b60008060808385031215614d4a578182fd5b614d53836143e5565b9150614c018460208501614402565b60008060408385031215614d74578182fd5b614d7d836143e5565b9150602083015167ffffffffffffffff80821115614d99578283fd5b9084019060408287031215614dac578283fd5b604051604081018181108382111715614dc757614dc7615d35565b604052825182811115614dd8578485fd5b614de488828601614566565b82525060208301519250614df783615d80565b8260208201528093505050509250929050565b60008060408385031215614e1c578182fd5b614e25836143e5565b9150602083015167ffffffffffffffff80821115614e41578283fd5b9084019060c08287031215614e54578283fd5b614e5c615a29565b825182811115614e6a578485fd5b614e7688828601614566565b825250614e85602084016143f7565b6020820152614e9660408401613f04565b6040820152614ea7606084016143f7565b6060820152608083015182811115614ebd578485fd5b614ec9888286016143a2565b608083015250614edb60a08401613f04565b60a08201528093505050509250929050565b60008060408385031215614eff578182fd5b614f08836143e5565b9150602083015167ffffffffffffffff811115614f23578182fd5b614f2f85828601614566565b9150509250929050565b60008060408385031215614f4b578182fd5b614f54836143e5565b9150602083015190509250929050565b600080600060608486031215614f78578081fd5b614f81846143e5565b9250602080850151614f9281615d92565b604086015190935067ffffffffffffffff811115614fae578283fd5b8501601f81018713614fbe578283fd5b8051614fcc613f2f82615ae7565b8082825284820191508484018a868560051b8701011115614feb578687fd5b8694505b8385101561484c57805161500281615d71565b835260019490940193918501918501614fef565b600060208284031215615027578081fd5b815161129681615d71565b60008060408385031215615044578182fd5b825161504f81615d71565b60208401519092506146e981615d63565b6000815180845260208085019450808401835b8381101561509257815160070b87529582019590820190600101615073565b509495945050505050565b6000815180845260208085019450808401835b83811015615092578151805163ffffffff168852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a090960195908201906001016150b0565b6000815180845260208085019450808401835b83811015615092578151805163ffffffff9081168952848201518116858a01526040808301518216908a01526060808301519091169089015260808082015115159089015260a0908101516001600160a01b03169088015260c0909601959082019060010161511f565b6000815180845260208085019450808401835b8381101561509257815180516001600160a01b03908116895284820151168489015260409081015160070b908801526060909601959082019060010161519c565b6000815180845260208085019450808401835b83811015615092578151805163ffffffff9081168952848201518116858a0152604080830151909116908901526060808201516001600160a01b03908116918a01919091526080808301511515908a015260a091820151169088015260c090960195908201906001016151f0565b6000815180845260208085019450848260051b8601828601855b8581101561438a5783830389528151604081518552868201519150808786015281511515818601528682015160606001600160a01b038083168289015283850151935060a09250608083818a01526152d360e08a0186615311565b92860151898403603f1901858b01529294506152ef8584615311565b9501511660c09790970196909652505098850198925090840190600101615278565b60008151808452615329816020860160208601615c98565b601f01601f19169290920160200192915050565b600081516040845261535260408501826154e8565b60209384015163ffffffff16949093019390935250919050565b6000610160825181855261538282860182615311565b9150506020830151848203602086015261539c8282615311565b91505060408301516153b960408601826001600160a01b03169052565b50606083015184820360608601526153d18282615311565b91505060808301516153e7608086018215159052565b5060a08301516153ff60a086018263ffffffff169052565b5060c083015161541360c086018215159052565b5060e083015184820360e086015261542b828261525e565b61010085810151805163ffffffff9081168984015260208201516001600160a01b03166101208a015260408201511661014089015291935091505090949350505050565b6000815160c0845261548460c08501826154e8565b9050602083015160070b602085015260408301516001600160a01b038082166040870152606085015160070b60608701526080850151915085830360808701526154ce8383615311565b92508060a08601511660a087015250508091505092915050565b600061012082518185526154fe8286018261536c565b915050602083015161551c602086018267ffffffffffffffff169052565b506040830151615530604086018215159052565b506060830151615544606086018215159052565b506080830151615558608086018215159052565b5060a083015184820360a0860152615570828261509d565b91505060c083015184820360c086015261558a828261510c565b91505060e083015184820360e08601526155a482826151dd565b91505061010080840151858303828701526155bf8382615311565b9695505050505050565b600082516155db818460208701615c98565b9190910192915050565b60006001600160a01b038086168352808516602084015250606060408301526156116060830184615060565b95945050505050565b6001600160a01b0383168152608081016112966020830184805163ffffffff90811683526020808301516001600160a01b03169084015260409182015116910152565b6000606082016001600160a01b0386168352602067ffffffffffffffff8616818501526060604085015281855180845260808601915060808160051b8701019350828701855b828110156156d157607f198887030184526156bf868351615311565b955092840192908401906001016156a3565b50939998505050505050505050565b6060815260006156f3606083018661509d565b8281036020840152615705818661510c565b905082810360408401526155bf81856151dd565b60006020808301818452808551808352604092508286019150828160051b870101848801865b838110156157de57888303603f19018552815180516001600160a01b0390811685528882015160608a870181905281519087018190526080870192918b0191908c905b808210156157b05783518051841686528d015160070b8d860152938b0193928c019260019190910190615782565b505050509087015184820385890152906157ca8183615189565b96890196945050509086019060010161573f565b509098975050505050505050565b828152608081016112966020830184805163ffffffff90811683526020808301516001600160a01b03169084015260409182015116910152565b8281526040602082015260006111d5604083018461533d565b8281526040602082015260006111d5604083018461546f565b8281526040602082015260006111d560408301846154e8565b83815267ffffffffffffffff831660208201526060604082015260006156116060830184615060565b8460070b81526080602082015260006158b6608083018661509d565b82810360408401526158c8818661510c565b905082810360608401526158dc81856151dd565b979650505050505050565b606081016109d58284805163ffffffff90811683526020808301516001600160a01b03169084015260409182015116910152565b602081526000611296602083018461533d565b602081526000611296602083018461536c565b606081526000615954606083018661536c565b60208301949094525060400152919050565b60a08152600061597960a083018861536c565b8660208401528560408401528281036060840152615997818661509d565b905082810360808401526159ab818561510c565b98975050505050505050565b602081526000611296602083018461546f565b60208152600061129660208301846154e8565b67ffffffffffffffff831681526040602082015260006111d56040830184615060565b60405160a0810167ffffffffffffffff81118282101715615a2357615a23615d35565b60405290565b60405160c0810167ffffffffffffffff81118282101715615a2357615a23615d35565b6040516060810167ffffffffffffffff81118282101715615a2357615a23615d35565b6040805190810167ffffffffffffffff81118282101715615a2357615a23615d35565b604051610120810167ffffffffffffffff81118282101715615a2357615a23615d35565b604051601f8201601f1916810167ffffffffffffffff81118282101715615adf57615adf615d35565b604052919050565b600067ffffffffffffffff821115615b0157615b01615d35565b5060051b60200190565b600067ffffffffffffffff821115615b2557615b25615d35565b50601f01601f191660200190565b6000615b41613f2f84615ae7565b808482526020808301925084368760051b87011115615b5e578485fd5b845b87811015615c8c57813567ffffffffffffffff80821115615b7f578788fd5b818901915060608236031215615b93578788fd5b615b9b615a4c565b8235615ba681615d4b565b81528286013582811115615bb857898afd5b830136601f820112615bc857898afd5b8035615bd6613f2f82615ae7565b81815288810190838a0136600685901b86018c011115615bf4578d8efd5b8d94505b83851015615c49576040808236031215615c10578e8ffd5b615c18615a6f565b8235615c2381615d4b565b8152828d0135615c3281615d71565b818e0152845260019590950194928b019201615bf8565b50848a01525060409150508381013583811115615c64578a8bfd5b615c70368287016140c3565b9183019190915250875250509382019390820190600101615b60565b50919695505050505050565b60005b83811015615cb3578181015183820152602001615c9b565b83811115615cc2576000848401525b50505050565b600181811c90821680615cdc57607f821691505b60208210811415615cfd57634e487b7160e01b600052602260045260246000fd5b50919050565b60008160070b677fffffffffffffff19811415615d2e57634e487b7160e01b82526011600452602482fd5b9003919050565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114615d6057600080fd5b50565b8015158114615d6057600080fd5b8060070b8114615d6057600080fd5b63ffffffff81168114615d6057600080fd5b67ffffffffffffffff81168114615d6057600080fdfe90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aaa2646970667358221220add164a69fb3649d7787cd01cf3367f3be73142d2ec952baba16ed091764156d64736f6c63430008040033", + "deployedBytecode": "0x6080604052600436106102dc5760003560e01c80638070905f11610184578063d85f74c1116100d6578063f2f38a741161008a578063f848fec411610064578063f848fec4146108b7578063f9e978bd146108d7578063fdc8321e146108f757600080fd5b8063f2f38a7414610849578063f4a01e5b14610877578063f7be34251461089757600080fd5b8063eee55ac8116100bb578063eee55ac8146107e9578063f25b120014610809578063f2c31ff41461082957600080fd5b8063d85f74c1146107b6578063d92ac248146107c957600080fd5b80639604ca6511610138578063af99c63311610112578063af99c63314610748578063c0b19b6d14610768578063d614cdb81461079657600080fd5b80639604ca65146106e8578063a345f7bd14610708578063a3ad5b551461072857600080fd5b80638ba74da0116101695780638ba74da01461067b5780638c99ef5d1461068e5780638f8d7f99146106c857600080fd5b80638070905f1461062c57806386f88d881461065b57600080fd5b80634cbdb37b1161023d5780635d2c5bad116101f15780636da6b1f0116101cb5780636da6b1f0146105cc5780637c41ad2c146105ec5780637d3e5da81461060c57600080fd5b80635d2c5bad1461054157806369837dc21461057e5780636a4dde21146105ac57600080fd5b8063593d6e8211610222578063593d6e82146104bc5780635a5e6c31146104dc5780635b9076b71461051157600080fd5b80634cbdb37b1461046e57806356af84031461049c57600080fd5b80632eecbca3116102945780633eed2c39116102795780633eed2c39146104195780634b5c6687146104395780634ba670351461044e57600080fd5b80632eecbca3146103d95780633b3bff0f146103f957600080fd5b806319db44b6116102c557806319db44b61461034e5780632b256ec81461038b5780632d73bb2e146103b957600080fd5b80630fd2601e146102e157806313c05dd814610319575b600080fd5b3480156102ed57600080fd5b506103016102fc3660046146bc565b610917565b60405160079190910b81526020015b60405180910390f35b34801561032557600080fd5b506103396103343660046146f4565b6109db565b60408051928352901515602083015201610310565b34801561035a57600080fd5b5061036e610369366004614a01565b610a59565b604080519283526001600160a01b03909116602083015201610310565b34801561039757600080fd5b506103ab6103a63660046146a0565b610add565b604051908152602001610310565b3480156103c557600080fd5b506103ab6103d43660046146bc565b610bc9565b3480156103e557600080fd5b506103016103f43660046146bc565b610c0e565b34801561040557600080fd5b506103ab6104143660046146a0565b610c45565b34801561042557600080fd5b506103396104343660046146a0565b610d1f565b61044c6104473660046146a0565b610d99565b005b34801561045a57600080fd5b506103ab61046936600461473e565b611191565b34801561047a57600080fd5b5061048e610489366004614959565b6111dd565b60405161031092919061583f565b3480156104a857600080fd5b506103ab6104b7366004614799565b611253565b3480156104c857600080fd5b506103ab6104d7366004614986565b61129d565b3480156104e857600080fd5b506104fc6104f73660046146f4565b61137a565b60408051928352602083019190915201610310565b34801561051d57600080fd5b5061053161052c3660046146a0565b6113eb565b604051610310949392919061589a565b34801561054d57600080fd5b5061056161055c3660046146a0565b61147d565b6040805160079390930b835260039190910b602083015201610310565b34801561058a57600080fd5b5061059e6105993660046146a0565b6114f8565b604051610310929190615826565b3480156105b857600080fd5b506103396105c73660046146bc565b61156d565b3480156105d857600080fd5b506103ab6105e736600461473e565b6115e4565b3480156105f857600080fd5b506103ab6106073660046146a0565b6115f2565b34801561061857600080fd5b506103ab6106273660046146bc565b611620565b34801561063857600080fd5b5061064c610647366004614a2c565b61162c565b60405161031093929190615871565b34801561066757600080fd5b506103396106763660046146a0565b6116b4565b61044c6106893660046146bc565b611725565b34801561069a57600080fd5b506106ae6106a93660046146a0565b611be1565b6040805160079390930b8352901515602083015201610310565b3480156106d457600080fd5b506103016106e33660046146bc565b611c5a565b3480156106f457600080fd5b506103ab610703366004614b3a565b611c90565b34801561071457600080fd5b506103ab6107233660046146a0565b611cc5565b34801561073457600080fd5b506106ae6107433660046146bc565b611d0b565b34801561075457600080fd5b506103016107633660046146bc565b611dfd565b34801561077457600080fd5b506107886107833660046146a0565b611e33565b6040516103109291906157ec565b3480156107a257600080fd5b506107886107b13660046146a0565b611f2a565b61044c6107c43660046146a0565b612034565b3480156107d557600080fd5b506103ab6107e436600461491a565b612412565b3480156107f557600080fd5b506103ab610804366004614986565b61241f565b34801561081557600080fd5b506103ab61082436600461485c565b6124b2565b34801561083557600080fd5b506106ae6108443660046146bc565b6124bf565b34801561085557600080fd5b506108696108643660046146a0565b61259a565b604051610310929190615858565b34801561088357600080fd5b506103ab6108923660046146bc565b61260f565b3480156108a357600080fd5b506103ab6108b23660046146a0565b61261b565b3480156108c357600080fd5b506103ab6108d23660046148da565b6126fe565b3480156108e357600080fd5b5061044c6108f2366004614baa565b61270b565b34801561090357600080fd5b506103ab61091236600461489b565b612758565b604051638f8d7f9960e01b81526001600160a01b038084166004830152821660248201526000903090638f8d7f99906044015b602060405180830381600087803b15801561096457600080fd5b505af1158015610978573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099c9190615016565b604051600782900b8152909150600080516020615da98339815191529060200160405180910390a1600781900b6016146109d557600080fd5b92915050565b6000806109e9858585612959565b6040518281529193509150600080516020615da98339815191529060200160405180910390a160168214610a1c57600080fd5b60405181151581527e1c2e72360171244b3bb8cc8ddd767820edf37138ad6f129fb3574b407c307d906020015b60405180910390a1935093915050565b600080610a668484612a58565b6040518281529193509150600080516020615da98339815191529060200160405180910390a160168214610a9957600080fd5b6040516001600160a01b03821681527fc2c78c7c31baf14949e75c51df12be56edb9af523cf82839c2869bbcf13b3ecb906020015b60405180910390a19250929050565b604051631f106b4b60e21b81526001600160a01b03821660048201526000903090637c41ad2c90602401602060405180830381600087803b158015610b2157600080fd5b505af1158015610b35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b599190614bc6565b9050600080516020615da983398151915281604051610b7a91815260200190565b60405180910390a160168114610b8f57600080fd5b604051600181527f0c9c765845f4d139956bb8fc8decb2eec6093c9c608b809641b16054b29f0e13906020015b60405180910390a1919050565b6000610bd58383612b38565b60070b9050600080516020615da983398151915281604051610bf991815260200190565b60405180910390a1601681146109d557600080fd5b60405163af99c63360e01b81526001600160a01b03808416600483015282166024820152600090309063af99c6339060440161094a565b6040516001600160a01b03821660248201526000908190819061016790633b3bff0f60e01b906044015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610cad91906155c9565b6000604051808303816000865af19150503d8060008114610cea576040519150601f19603f3d011682016040523d82523d6000602084013e610cef565b606091505b509150915081610d00576015610d14565b80806020019051810190610d149190614c0a565b60030b949350505050565b600080610d2b83612b87565b6040518281529193509150600080516020615da98339815191529060200160405180910390a160168214610d5e57600080fd5b60405181151581527f6b7f3306751292f85ab4161ee2b0ac16dfc8ded13e6446ce6bd859d0a2f4c78e906020015b60405180910390a1915091565b60408051600480825260a08201909252600091816020015b610db9613d8e565b815260200190600190039081610db1579050509050610dec60006006600160405180602001604052806000815250612c84565b81600081518110610e0d57634e487b7160e01b600052603260045260246000fd5b6020026020010181905250610e3360018060405180602001604052806000815250612cbb565b81600181518110610e5457634e487b7160e01b600052603260045260246000fd5b6020026020010181905250610e7b6002600160405180602001604052806000815250612cbb565b81600281518110610e9c57634e487b7160e01b600052603260045260246000fd5b6020026020010181905250610ec36003600160405180602001604052806000815250612cbb565b81600381518110610ee457634e487b7160e01b600052603260045260246000fd5b602002602001018190525060006040518060600160405280600063ffffffff168152602001846001600160a01b03168152602001627a120063ffffffff168152509050600060405180610120016040528060018054610f4290615cc8565b80601f0160208091040260200160405190810160405280929190818152602001828054610f6e90615cc8565b8015610fbb5780601f10610f9057610100808354040283529160200191610fbb565b820191906000526020600020905b815481529060010190602001808311610f9e57829003601f168201915b5050505050815260200160028054610fd290615cc8565b80601f0160208091040260200160405190810160405280929190818152602001828054610ffe90615cc8565b801561104b5780601f106110205761010080835404028352916020019161104b565b820191906000526020600020905b81548152906001019060200180831161102e57829003601f168201915b50505050508152602001856001600160a01b031681526020016003805461107190615cc8565b80601f016020809104026020016040519081016040528092919081815260200182805461109d90615cc8565b80156110ea5780601f106110bf576101008083540402835291602001916110ea565b820191906000526020600020905b8154815290600101906020018083116110cd57829003601f168201915b50505091835250506001602082015260055463ffffffff16604082015260075460ff16151560608201526080810185905260a001839052600454600654919250600091829161113b91859190612cf0565b90925090506016821461114d57600080fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050565b600061119f85858585612e1e565b9050600080516020615da9833981519152816040516111c091815260200190565b60405180910390a1601681146111d557600080fd5b949350505050565b60006111e7613deb565b6111f18484612f2e565b6040518281529193509150600080516020615da98339815191529060200160405180910390a16016821461122457600080fd5b7fa516f81c528634d0fc1e993bba1d227231b4bd6d1beb72d33b056a6199c0f98881604051610ace91906159b7565b6000611260848484613021565b9050600080516020615da98339815191528160405161128191815260200190565b60405180910390a16016811461129657600080fd5b9392505050565b60008060006101676001600160a01b031663593d6e8260e01b86866040516024016112c992919061561a565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161130791906155c9565b6000604051808303816000865af19150503d8060008114611344576040519150601f19603f3d011682016040523d82523d6000602084013e611349565b606091505b50915091508161135a57601561136e565b8080602001905181019061136e9190614c0a565b60030b95945050505050565b600080611388858585613101565b6040518281529193509150600080516020615da98339815191529060200160405180910390a1601682146113bb57600080fd5b6040518181527f25b6684a7e8fe1b676e9c39c8dd65034fbafea906d3bdfd97bf748b7b55e14c890602001610a49565b600060608060606113fb856131ed565b604051600785900b815293975091955093509150600080516020615da98339815191529060200160405180910390a1600784900b60161461143b57600080fd5b7f2efc8334b040613a552197fe34283d6ca2909c8ffae393e128424931f20c69b383838360405161146e939291906156e0565b60405180910390a19193509193565b600080611489836132ed565b604051600783900b81529193509150600080516020615da98339815191529060200160405180910390a1600782900b6016146114c457600080fd5b604051600382900b81527f182137409609594f2b12128230091c673507ea4cab315d59415d5e3f8c301ad590602001610d8c565b6000611502613e26565b61150b836133ca565b6040518281529193509150600080516020615da98339815191529060200160405180910390a16016821461153e57600080fd5b7f476a9a9b28e2717d55288b2ae3c48a72aac52b11f8bd855017c9d41d9fc1896481604051610d8c919061591b565b60008061157a84846134b3565b60405160079290920b80835293509150600080516020615da98339815191529060200160405180910390a1601682146115b257600080fd5b60405181151581527f59800d968fcce138300a0019410b4b75041610d65b3cdc5f31656b03ed14912e90602001610ace565b600061119f85858585613504565b6040516001600160a01b03821660248201526000908190819061016790631f106b4b60e21b90604401610c6f565b6000610bd58383613565565b600080606061163c8686866135b4565b6040518381529295509093509150600080516020615da98339815191529060200160405180910390a16016831461167257600080fd5b7feff23992f47b3c101679f8b4dc9d3e242c903909dba4a453f2b2341ad463b0e282826040516116a39291906159dd565b60405180910390a193509350939050565b6000806116c0836136b2565b6040518281529193509150600080516020615da98339815191529060200160405180910390a1601682146116f357600080fd5b60405181151581527f9ee19e13dfa1ba8db2502e15ff56dbecdeb0e0473323fb195473ce648030a2cd90602001610d8c565b604080516001808252818301909252600091816020015b611744613d8e565b81526020019060019003908161173c579050509050611776600080600160405180602001604052806000815250612c84565b8160008151811061179757634e487b7160e01b600052603260045260246000fd5b602002602001018190525060006040518060600160405280600063ffffffff168152602001856001600160a01b03168152602001627a120063ffffffff1681525090506000604051806101200160405280600180546117f590615cc8565b80601f016020809104026020016040519081016040528092919081815260200182805461182190615cc8565b801561186e5780601f106118435761010080835404028352916020019161186e565b820191906000526020600020905b81548152906001019060200180831161185157829003601f168201915b505050505081526020016002805461188590615cc8565b80601f01602080910402602001604051908101604052809291908181526020018280546118b190615cc8565b80156118fe5780601f106118d3576101008083540402835291602001916118fe565b820191906000526020600020905b8154815290600101906020018083116118e157829003601f168201915b50505050508152602001866001600160a01b031681526020016003805461192490615cc8565b80601f016020809104026020016040519081016040528092919081815260200182805461195090615cc8565b801561199d5780601f106119725761010080835404028352916020019161199d565b820191906000526020600020905b81548152906001019060200180831161198057829003601f168201915b505050918352505060016020820181905260055463ffffffff166040808401919091526000606084018190526080840188905260a09093018690528051828152808201909152929350909190816020015b6040805160a0810182526000808252602080830182905292820181905260608201819052608082015282526000199092019101816119ee5750506040805160a081018252600181526001600160a01b03888116602083015260009282018390526060820183905289166080820152825192935091839190611a7f57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152604080516001808252818301909252600091816020015b6040805160c08101825260008082526020808301829052928201819052606082018190526080820181905260a08201528252600019909201910181611aa15750506040805160c0810182526004815260056020820152600a91810191909152601e60608201526000608082018190526001600160a01b038a1660a083015282519293509091839190611b4357634e487b7160e01b600052603260045260246000fd5b6020026020010181905250600080611b628560045460065487876136fb565b91509150600080516020615da983398151915282604051611b8591815260200190565b60405180910390a160168214611b9a57600080fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050505050565b600080611bed8361382f565b604051600783900b81529193509150600080516020615da98339815191529060200160405180910390a1600782900b601614611c2857600080fd5b60405181151581527f5080c42cc33acbcea410fa6eaa925bd878674825501981184fdd53749f8478a890602001610d8c565b6040516001600160a01b038381166024830152821660448201526000908190819061016790638f8d7f9960e01b906064016112c9565b6000611ca4611c9f8385615b33565b613878565b9050600080516020615da983398151915281604051610bf991815260200190565b6000611cd0826138a2565b9050600080516020615da983398151915281604051611cf191815260200190565b60405180910390a160168114611d0657600080fd5b919050565b604051633cb0c7fd60e21b81526001600160a01b038084166004830152821660248201526000908190309063f2c31ff4906044016040805180830381600087803b158015611d5857600080fd5b505af1158015611d6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d909190615032565b604051600783900b81529193509150600080516020615da98339815191529060200160405180910390a1600782900b601614611dcb57600080fd5b60405181151581527fd24dda6928587354b65aa1a18c2eaf249bef7e5bafd2a71fac71d286f76f957f90602001610ace565b6040516001600160a01b03838116602483015282166044820152600090819081906101679063af99c63360e01b906064016112c9565b60408051606081018252600080825260208201819052918101829052604051631ac299b760e31b81526001600160a01b0384166004820152309063d614cdb890602401608060405180830381600087803b158015611e9057600080fd5b505af1158015611ea4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec89190614bde565b6040518281529193509150600080516020615da98339815191529060200160405180910390a160168214611efb57600080fd5b7fa0a16bf9db2c17796faeca5af5aaeef8523f9d4c350c512cb00062ad89604f8881604051610d8c91906158e7565b604080516060810182526000808252602080830182905282840182905283516001600160a01b038616602480830191909152855180830390910181526044909101855290810180516001600160e01b0316631ac299b760e31b179052925190928391829161016791611f9c91906155c9565b6000604051808303816000865af19150503d8060008114611fd9576040519150601f19603f3d011682016040523d82523d6000602084013e611fde565b606091505b50604080516060810182526000808252602082018190529181019190915291935091508261200e57601581612022565b818060200190518101906120229190614d38565b60039190910b97909650945050505050565b60408051600580825260c08201909252600091816020015b612054613d8e565b81526020019060019003908161204c57905050905061208760006006600160405180602001604052806000815250612c84565b816000815181106120a857634e487b7160e01b600052603260045260246000fd5b60200260200101819052506120ce60018060405180602001604052806000815250612cbb565b816001815181106120ef57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506121166002600160405180602001604052806000815250612cbb565b8160028151811061213757634e487b7160e01b600052603260045260246000fd5b602002602001018190525061215e6004600160405180602001604052806000815250612cbb565b8160038151811061217f57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506121a66003600160405180602001604052806000815250612cbb565b816004815181106121c757634e487b7160e01b600052603260045260246000fd5b602002602001018190525060006040518060600160405280600063ffffffff168152602001846001600160a01b03168152602001627a120063ffffffff16815250905060006040518061012001604052806001805461222590615cc8565b80601f016020809104026020016040519081016040528092919081815260200182805461225190615cc8565b801561229e5780601f106122735761010080835404028352916020019161229e565b820191906000526020600020905b81548152906001019060200180831161228157829003601f168201915b50505050508152602001600280546122b590615cc8565b80601f01602080910402602001604051908101604052809291908181526020018280546122e190615cc8565b801561232e5780601f106123035761010080835404028352916020019161232e565b820191906000526020600020905b81548152906001019060200180831161231157829003601f168201915b50505050508152602001856001600160a01b031681526020016003805461235490615cc8565b80601f016020809104026020016040519081016040528092919081815260200182805461238090615cc8565b80156123cd5780601f106123a2576101008083540402835291602001916123cd565b820191906000526020600020905b8154815290600101906020018083116123b057829003601f168201915b50505091835250506001602082015260055463ffffffff16604082015260075460ff16151560608201526080810185905260a001839052905060008061113b836138e9565b60006112608484846139d3565b6040517f593d6e82000000000000000000000000000000000000000000000000000000008152600090309063593d6e8290612460908690869060040161561a565b602060405180830381600087803b15801561247a57600080fd5b505af115801561248e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca49190614bc6565b6000611260848484613a2e565b6040516001600160a01b0383811660248301528216604482015260009081908190819061016790633cb0c7fd60e21b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161253191906155c9565b6000604051808303816000865af19150503d806000811461256e576040519150601f19603f3d011682016040523d82523d6000602084013e612573565b606091505b5091509150816125865760156000612022565b808060200190518101906120229190614ce4565b60006125a4613e46565b6125ad83613a85565b6040518281529193509150600080516020615da98339815191529060200160405180910390a1601682146125e057600080fd5b7f528c7dcea75f0c9e110a038e50647cd6a70ac06d331399b77dd9a80f903ebc1681604051610d8c91906159ca565b6000611ca48383613b6e565b604051633b3bff0f60e01b81526001600160a01b03821660048201526000903090633b3bff0f90602401602060405180830381600087803b15801561265f57600080fd5b505af1158015612673573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126979190614bc6565b9050600080516020615da9833981519152816040516126b891815260200190565b60405180910390a1601681146126cd57600080fd5b604051600181527f319ab7084208e4afa38c6e6ff7aea9587439f2e4700746f4c7d425fea17426d290602001610bbc565b6000611260848484613bbd565b6007805460ff191682151590811790915560405160ff909116151581527f457c3a16a0ebdc38e3675609957ca3fcc4490e220bd15d85d34f58e2e145cb089060200160405180910390a150565b6040805160008082526020820190925281908161279d565b60408051606081018252600080825260208083018290529282015282526000199092019101816127705790505b50905060006040518060400160405280336001600160a01b03168152602001856127c690615d03565b600790810b9091526040805180820182526001600160a01b038a1681529187900b602083015280516002808252606082019092529293509091600091816020015b6040805180820190915260008082526020820152815260200190600190039081612807579050509050828160008151811061285257634e487b7160e01b600052603260045260246000fd5b6020026020010181905250818160018151811061287f57634e487b7160e01b600052603260045260246000fd5b602090810291909101810191909152604080516060810182526001600160a01b038a16815291820183905281810186905280516001808252818301909252600091816020015b6128f2604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816128c5579050509050818160008151811061292957634e487b7160e01b600052603260045260246000fd5b602002602001018190525061293d81613878565b96506016871461294c57600080fd5b5050505050509392505050565b604080516001600160a01b0385811660248301528481166044830152831660648083019190915282518083039091018152608490910182526020810180516001600160e01b03167ff49f40db000000000000000000000000000000000000000000000000000000001790529051600091829182918291610167916129dc916155c9565b6000604051808303816000865af19150503d8060008114612a19576040519150601f19603f3d011682016040523d82523d6000602084013e612a1e565b606091505b509150915081612a315760156000612a45565b80806020019051810190612a459190614ce4565b60039190910b9890975095505050505050565b604080516001600160a01b0384166024820152604480820184905282518083039091018152606490910182526020810180516001600160e01b03167f098f236600000000000000000000000000000000000000000000000000000000179052905160009182918291829161016791612acf916155c9565b6000604051808303816000865af19150503d8060008114612b0c576040519150601f19603f3d011682016040523d82523d6000602084013e612b11565b606091505b509150915081612b245760156000612022565b808060200190518101906120229190614c24565b6040516001600160a01b0383811660248301528216604482015260009081908190610167907f52f9138700000000000000000000000000000000000000000000000000000000906064016112c9565b6040516001600160a01b0382166024820152600090819081908190610167907fa7daa18d00000000000000000000000000000000000000000000000000000000906044015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612c0a91906155c9565b6000604051808303816000865af19150503d8060008114612c47576040519150601f19603f3d011682016040523d82523d6000602084013e612c4c565b606091505b509150915081612c5f5760156000612c73565b80806020019051810190612c739190614ce4565b60039190910b969095509350505050565b612c8c613d8e565b6040518060400160405280612ca18787613c13565b8152602001612cb08585613c2c565b905295945050505050565b612cc3613d8e565b6040518060400160405280612cd786613cfc565b8152602001612ce68585613c2c565b9052949350505050565b600080848061010001516000015163ffffffff166000148015612d2057506101008101516040015163ffffffff16155b15612d36576101008101516276a7006040909101525b6000806101676001600160a01b031634637812a04b60e01b8a8a8a604051602401612d6393929190615941565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612da191906155c9565b60006040518083038185875af1925050503d8060008114612dde576040519150601f19603f3d011682016040523d82523d6000602084013e612de3565b606091505b509150915081612df65760156000612e0a565b80806020019051810190612e0a9190614c24565b60039190910b999098509650505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b608482015260009081908190610167907feca36917000000000000000000000000000000000000000000000000000000009060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612eb991906155c9565b6000604051808303816000865af19150503d8060008114612ef6576040519150601f19603f3d011682016040523d82523d6000602084013e612efb565b606091505b509150915081612f0c576015612f20565b80806020019051810190612f209190614c0a565b60030b979650505050505050565b6000612f38613deb565b604080516001600160a01b0386166024820152600785900b60448083019190915282518083039091018152606490910182526020810180516001600160e01b03167f287e1da8000000000000000000000000000000000000000000000000000000001790529051600091829161016791612fb1916155c9565b6000604051808303816000865af19150503d8060008114612fee576040519150601f19603f3d011682016040523d82523d6000602084013e612ff3565b606091505b5091509150613000613deb565b8261300d57601581612a45565b81806020019051810190612a459190614e0a565b60008060006101676001600160a01b031663f7f38e2660e01b87878760405160240161304f939291906155e5565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161308d91906155c9565b6000604051808303816000865af19150503d80600081146130ca576040519150601f19603f3d011682016040523d82523d6000602084013e6130cf565b606091505b5091509150816130e05760156130f4565b808060200190518101906130f49190614c0a565b60030b9695505050505050565b604080516001600160a01b0385811660248301528481166044830152831660648083019190915282518083039091018152608490910182526020810180516001600160e01b03167f927da10500000000000000000000000000000000000000000000000000000000179052905160009182918291829161016791613184916155c9565b6000604051808303816000865af19150503d80600081146131c1576040519150601f19603f3d011682016040523d82523d6000602084013e6131c6565b606091505b5091509150816131d95760156000612a45565b80806020019051810190612a459190614f39565b604080516001600160a01b03831660248083019190915282518083039091018152604490910182526020810180516001600160e01b03167fae7611a0000000000000000000000000000000000000000000000000000000001790529051600091606091829182918591829161016791613265916155c9565b6000604051808303816000865af19150503d80600081146132a2576040519150601f19603f3d011682016040523d82523d6000602084013e6132a7565b606091505b50915091506060806060846132c05760158383836132d4565b838060200190518101906132d49190614c4f565b60039390930b9d919c509a509098509650505050505050565b604080516001600160a01b03831660248083019190915282518083039091018152604490910182526020810180516001600160e01b03167f93272baf00000000000000000000000000000000000000000000000000000000179052905160009182918291829161016791613360916155c9565b6000604051808303816000865af19150503d806000811461339d576040519150601f19603f3d011682016040523d82523d6000602084013e6133a2565b606091505b5091509150816133b6576015600019612c73565b80806020019051810190612c739190614d0f565b60006133d4613e26565b604080516001600160a01b03851660248083019190915282518083039091018152604490910182526020810180516001600160e01b03167f3f28a19b000000000000000000000000000000000000000000000000000000001790529051600091829161016791613443916155c9565b6000604051808303816000865af19150503d8060008114613480576040519150601f19603f3d011682016040523d82523d6000602084013e613485565b606091505b5091509150613492613e26565b8261349f57601581612022565b818060200190518101906120229190614d62565b6040516001600160a01b03838116602483015282166044820152600090819081908190610167907f46de0fb100000000000000000000000000000000000000000000000000000000906064016124f3565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b608482015260009081908190610167907f5cfc9011000000000000000000000000000000000000000000000000000000009060a401612e7b565b6040516001600160a01b0383811660248301528216604482015260009081908190610167907f5b8f858400000000000000000000000000000000000000000000000000000000906064016112c9565b60008060606000806101676001600160a01b031663278e0b8860e01b8989896040516024016135e59392919061565d565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161362391906155c9565b6000604051808303816000865af19150503d8060008114613660576040519150601f19603f3d011682016040523d82523d6000602084013e613665565b606091505b50915091508161368857604080516000808252602082019092526015919061369c565b8080602001905181019061369c9190614f64565b60039290920b9a90995090975095505050505050565b6040516001600160a01b0382166024820152600090819081908190610167907f335e04c10000000000000000000000000000000000000000000000000000000090604401612bcc565b600080868061010001516000015163ffffffff16600014801561372b57506101008101516040015163ffffffff16155b15613741576101008101516276a7006040909101525b6000806101676001600160a01b031634634c381ae760e01b8c8c8c8c8c604051602401613772959493929190615966565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516137b091906155c9565b60006040518083038185875af1925050503d80600081146137ed576040519150601f19603f3d011682016040523d82523d6000602084013e6137f2565b606091505b5091509150816138055760156000613819565b808060200190518101906138199190614c24565b60039190910b9b909a5098505050505050505050565b6040516001600160a01b0382166024820152600090819081908190610167907f19f373610000000000000000000000000000000000000000000000000000000090604401612bcc565b60008060006101676001600160a01b031663189a554c60e01b85604051602401610c6f9190615719565b6040516001600160a01b038216602482015260009081908190610167907ff069f7120000000000000000000000000000000000000000000000000000000090604401610c6f565b600080828061010001516000015163ffffffff16600014801561391957506101008101516040015163ffffffff16155b1561392f576101008101516276a7006040909101525b6000806101676001600160a01b031634639dc711e060e01b88604051602401613958919061592e565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161399691906155c9565b60006040518083038185875af1925050503d8060008114612b0c576040519150601f19603f3d011682016040523d82523d6000602084013e612b11565b6040516001600160a01b0384811660248301528316604482015263ffffffff8216606482015260009081908190610167907f9790686d000000000000000000000000000000000000000000000000000000009060840161304f565b6040516001600160a01b03848116602483015283166044820152811515606482015260009081908190610167907f367605ca000000000000000000000000000000000000000000000000000000009060840161304f565b6000613a8f613e46565b604080516001600160a01b03851660248083019190915282518083039091018152604490910182526020810180516001600160e01b03167f1f69565f000000000000000000000000000000000000000000000000000000001790529051600091829161016791613afe916155c9565b6000604051808303816000865af19150503d8060008114613b3b576040519150601f19603f3d011682016040523d82523d6000602084013e613b40565b606091505b5091509150613b4d613e46565b82613b5a57601581612022565b818060200190518101906120229190614eed565b6040516001600160a01b0383811660248301528216604482015260009081908190610167907f49146bde00000000000000000000000000000000000000000000000000000000906064016112c9565b6040516001600160a01b038481166024830152831660448201526064810182905260009081908190610167907fe1f21c67000000000000000000000000000000000000000000000000000000009060840161304f565b6000600160ff84161b9050600160ff83161b8117611296565b613c726040518060a0016040528060001515815260200160006001600160a01b03168152602001606081526020016060815260200160006001600160a01b031681525090565b8260ff1660011415613c8757600181526109d5565b8260ff1660021415613ca9576000546001600160a01b031660208201526109d5565b8260ff1660031415613cc157604081018290526109d5565b8260ff1660041415613cd957606081018290526109d5565b8260ff16600514156109d5576000546001600160a01b0316608082015292915050565b600060ff8216613d0e57506001919050565b8160ff1660011415613d2257506002919050565b8160ff1660021415613d3657506004919050565b8160ff1660031415613d4a57506008919050565b8160ff1660041415613d5e57506010919050565b8160ff1660051415613d7257506020919050565b8160ff1660061415613d8657506040919050565b506000919050565b604051806040016040528060008152602001613de66040518060a0016040528060001515815260200160006001600160a01b03168152602001606081526020016060815260200160006001600160a01b031681525090565b905290565b6040518060c00160405280613dfe613e46565b8152600060208201819052604082018190526060808301829052608083015260a09091015290565b6040518060400160405280613e39613e46565b8152600060209091015290565b60408051610240810182526060610120820181815261014083018290526000610160840181905261018084018390526101a084018190526101c084018190526101e0840181905261020084018390528451928301855280835260208301819052938201939093526102208201529081908152602001600067ffffffffffffffff168152602001600015158152602001600015158152602001600015158152602001606081526020016060815260200160608152602001606081525090565b8051611d0681615d4b565b600082601f830112613f1f578081fd5b81516020613f34613f2f83615ae7565b615ab6565b8281528181019085830160a080860288018501891015613f52578687fd5b865b86811015613fdb5781838b031215613f6a578788fd5b613f72615a00565b8351613f7d81615d80565b815283870151613f8c81615d4b565b81880152604084810151613f9f81615d63565b90820152606084810151613fb281615d63565b90820152608084810151613fc581615d4b565b9082015285529385019391810191600101613f54565b509198975050505050505050565b600082601f830112613ff9578081fd5b81516020614009613f2f83615ae7565b8281528181019085830160c080860288018501891015614027578687fd5b865b86811015613fdb5781838b03121561403f578788fd5b614047615a29565b835161405281615d80565b81528387015161406181615d80565b8188015260408481015161407481615d80565b9082015260608481015161408781615d80565b9082015260808481015161409a81615d63565b9082015260a0848101516140ad81615d4b565b9082015285529385019391810191600101614029565b600082601f8301126140d3578081fd5b813560206140e3613f2f83615ae7565b82815281810190858301606080860288018501891015614101578687fd5b865b86811015613fdb5781838b031215614119578788fd5b614121615a4c565b833561412c81615d4b565b81528387013561413b81615d4b565b8188015260408481013561414e81615d71565b9082015285529385019391810191600101614103565b600082601f830112614174578081fd5b81516020614184613f2f83615ae7565b8281528181019085830160c0808602880185018910156141a2578687fd5b865b86811015613fdb5781838b0312156141ba578788fd5b6141c2615a29565b83516141cd81615d80565b8152838701516141dc81615d80565b818801526040848101516141ef81615d80565b9082015260608481015161420281615d4b565b9082015260808481015161421581615d63565b9082015260a08481015161422881615d4b565b90820152855293850193918101916001016141a4565b600082601f83011261424e578081fd5b8151602061425e613f2f83615ae7565b80838252828201915082860187848660051b890101111561427d578586fd5b855b8581101561438a57815167ffffffffffffffff8082111561429e578889fd5b90890190601f196040838d03820112156142b657898afd5b6142be615a6f565b8884015181526040840151838111156142d5578b8cfd5b939093019260a0848e03830112156142eb578a8bfd5b6142f3615a00565b91508884015161430281615d63565b825261431060408501613f04565b89830152606084015183811115614325578b8cfd5b6143338e8b838801016143a2565b60408401525060808401518381111561434a578b8cfd5b6143588e8b838801016143a2565b60608401525061436a60a08501613f04565b60808301528089019190915286525050928401929084019060010161427f565b5090979650505050505050565b8051611d0681615d63565b600082601f8301126143b2578081fd5b81516143c0613f2f82615b0b565b8181528460208386010111156143d4578283fd5b6111d5826020830160208701615c98565b8051600381900b8114611d0657600080fd5b8051611d0681615d71565b600060608284031215614413578081fd5b61441b615a4c565b9050815161442881615d80565b8152602082015161443881615d4b565b6020820152604082015161444b81615d80565b604082015292915050565b60006101608284031215614468578081fd5b614470615a92565b9050815167ffffffffffffffff8082111561448a57600080fd5b614496858386016143a2565b835260208401519150808211156144ac57600080fd5b6144b8858386016143a2565b60208401526144c960408501613f04565b604084015260608401519150808211156144e257600080fd5b6144ee858386016143a2565b60608401526144ff60808501614397565b608084015261451060a0850161468a565b60a084015261452160c08501614397565b60c084015260e084015191508082111561453a57600080fd5b506145478482850161423e565b60e08301525061010061455c84828501614402565b9082015292915050565b60006101208284031215614578578081fd5b614580615a92565b9050815167ffffffffffffffff8082111561459a57600080fd5b6145a685838601614456565b83526145b460208501614695565b60208401526145c560408501614397565b60408401526145d660608501614397565b60608401526145e760808501614397565b608084015260a084015191508082111561460057600080fd5b61460c85838601613f0f565b60a084015260c084015191508082111561462557600080fd5b61463185838601613fe9565b60c084015260e084015191508082111561464a57600080fd5b61465685838601614164565b60e08401526101009150818401518181111561467157600080fd5b61467d868287016143a2565b8385015250505092915050565b8051611d0681615d80565b8051611d0681615d92565b6000602082840312156146b1578081fd5b813561129681615d4b565b600080604083850312156146ce578081fd5b82356146d981615d4b565b915060208301356146e981615d4b565b809150509250929050565b600080600060608486031215614708578081fd5b833561471381615d4b565b9250602084013561472381615d4b565b9150604084013561473381615d4b565b809150509250925092565b60008060008060808587031215614753578182fd5b843561475e81615d4b565b9350602085013561476e81615d4b565b9250604085013561477e81615d4b565b9150606085013561478e81615d71565b939692955090935050565b6000806000606084860312156147ad578081fd5b83356147b881615d4b565b92506020848101356147c981615d4b565b9250604085013567ffffffffffffffff8111156147e4578283fd5b8501601f810187136147f4578283fd5b8035614802613f2f82615ae7565b8082825284820191508484018a868560051b8701011115614821578687fd5b8694505b8385101561484c57803561483881615d71565b835260019490940193918501918501614825565b5080955050505050509250925092565b600080600060608486031215614870578081fd5b833561487b81615d4b565b9250602084013561488b81615d4b565b9150604084013561473381615d63565b6000806000606084860312156148af578081fd5b83356148ba81615d4b565b925060208401356148ca81615d4b565b9150604084013561473381615d71565b6000806000606084860312156148ee578081fd5b83356148f981615d4b565b9250602084013561490981615d4b565b929592945050506040919091013590565b60008060006060848603121561492e578081fd5b833561493981615d4b565b9250602084013561494981615d4b565b9150604084013561473381615d80565b6000806040838503121561496b578182fd5b823561497681615d4b565b915060208301356146e981615d71565b6000808284036080811215614999578283fd5b83356149a481615d4b565b92506060601f19820112156149b7578182fd5b506149c0615a4c565b60208401356149ce81615d80565b815260408401356149de81615d4b565b602082015260608401356149f181615d80565b6040820152919491935090915050565b60008060408385031215614a13578182fd5b8235614a1e81615d4b565b946020939093013593505050565b600080600060608486031215614a40578081fd5b8335614a4b81615d4b565b9250602084810135614a5c81615d92565b9250604085013567ffffffffffffffff80821115614a78578384fd5b818701915087601f830112614a8b578384fd5b8135614a99613f2f82615ae7565b8082825285820191508585018b878560051b8801011115614ab8578788fd5b875b84811015614b2857813586811115614ad057898afd5b8701603f81018e13614ae057898afd5b88810135614af0613f2f82615b0b565b8181528f6040838501011115614b04578b8cfd5b81604084018c8301379081018a018b90528552509287019290870190600101614aba565b50508096505050505050509250925092565b60008060208385031215614b4c578182fd5b823567ffffffffffffffff80821115614b63578384fd5b818501915085601f830112614b76578384fd5b813581811115614b84578485fd5b8660208260051b8501011115614b98578485fd5b60209290920196919550909350505050565b600060208284031215614bbb578081fd5b813561129681615d63565b600060208284031215614bd7578081fd5b5051919050565b60008060808385031215614bf0578182fd5b82519150614c018460208501614402565b90509250929050565b600060208284031215614c1b578081fd5b611296826143e5565b60008060408385031215614c36578182fd5b614c3f836143e5565b915060208301516146e981615d4b565b60008060008060808587031215614c64578182fd5b614c6d856143e5565b9350602085015167ffffffffffffffff80821115614c89578384fd5b614c9588838901613f0f565b94506040870151915080821115614caa578384fd5b614cb688838901613fe9565b93506060870151915080821115614ccb578283fd5b50614cd887828801614164565b91505092959194509250565b60008060408385031215614cf6578182fd5b614cff836143e5565b915060208301516146e981615d63565b60008060408385031215614d21578182fd5b614d2a836143e5565b9150614c01602084016143e5565b60008060808385031215614d4a578182fd5b614d53836143e5565b9150614c018460208501614402565b60008060408385031215614d74578182fd5b614d7d836143e5565b9150602083015167ffffffffffffffff80821115614d99578283fd5b9084019060408287031215614dac578283fd5b604051604081018181108382111715614dc757614dc7615d35565b604052825182811115614dd8578485fd5b614de488828601614566565b82525060208301519250614df783615d80565b8260208201528093505050509250929050565b60008060408385031215614e1c578182fd5b614e25836143e5565b9150602083015167ffffffffffffffff80821115614e41578283fd5b9084019060c08287031215614e54578283fd5b614e5c615a29565b825182811115614e6a578485fd5b614e7688828601614566565b825250614e85602084016143f7565b6020820152614e9660408401613f04565b6040820152614ea7606084016143f7565b6060820152608083015182811115614ebd578485fd5b614ec9888286016143a2565b608083015250614edb60a08401613f04565b60a08201528093505050509250929050565b60008060408385031215614eff578182fd5b614f08836143e5565b9150602083015167ffffffffffffffff811115614f23578182fd5b614f2f85828601614566565b9150509250929050565b60008060408385031215614f4b578182fd5b614f54836143e5565b9150602083015190509250929050565b600080600060608486031215614f78578081fd5b614f81846143e5565b9250602080850151614f9281615d92565b604086015190935067ffffffffffffffff811115614fae578283fd5b8501601f81018713614fbe578283fd5b8051614fcc613f2f82615ae7565b8082825284820191508484018a868560051b8701011115614feb578687fd5b8694505b8385101561484c57805161500281615d71565b835260019490940193918501918501614fef565b600060208284031215615027578081fd5b815161129681615d71565b60008060408385031215615044578182fd5b825161504f81615d71565b60208401519092506146e981615d63565b6000815180845260208085019450808401835b8381101561509257815160070b87529582019590820190600101615073565b509495945050505050565b6000815180845260208085019450808401835b83811015615092578151805163ffffffff168852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a090960195908201906001016150b0565b6000815180845260208085019450808401835b83811015615092578151805163ffffffff9081168952848201518116858a01526040808301518216908a01526060808301519091169089015260808082015115159089015260a0908101516001600160a01b03169088015260c0909601959082019060010161511f565b6000815180845260208085019450808401835b8381101561509257815180516001600160a01b03908116895284820151168489015260409081015160070b908801526060909601959082019060010161519c565b6000815180845260208085019450808401835b83811015615092578151805163ffffffff9081168952848201518116858a0152604080830151909116908901526060808201516001600160a01b03908116918a01919091526080808301511515908a015260a091820151169088015260c090960195908201906001016151f0565b6000815180845260208085019450848260051b8601828601855b8581101561438a5783830389528151604081518552868201519150808786015281511515818601528682015160606001600160a01b038083168289015283850151935060a09250608083818a01526152d360e08a0186615311565b92860151898403603f1901858b01529294506152ef8584615311565b9501511660c09790970196909652505098850198925090840190600101615278565b60008151808452615329816020860160208601615c98565b601f01601f19169290920160200192915050565b600081516040845261535260408501826154e8565b60209384015163ffffffff16949093019390935250919050565b6000610160825181855261538282860182615311565b9150506020830151848203602086015261539c8282615311565b91505060408301516153b960408601826001600160a01b03169052565b50606083015184820360608601526153d18282615311565b91505060808301516153e7608086018215159052565b5060a08301516153ff60a086018263ffffffff169052565b5060c083015161541360c086018215159052565b5060e083015184820360e086015261542b828261525e565b61010085810151805163ffffffff9081168984015260208201516001600160a01b03166101208a015260408201511661014089015291935091505090949350505050565b6000815160c0845261548460c08501826154e8565b9050602083015160070b602085015260408301516001600160a01b038082166040870152606085015160070b60608701526080850151915085830360808701526154ce8383615311565b92508060a08601511660a087015250508091505092915050565b600061012082518185526154fe8286018261536c565b915050602083015161551c602086018267ffffffffffffffff169052565b506040830151615530604086018215159052565b506060830151615544606086018215159052565b506080830151615558608086018215159052565b5060a083015184820360a0860152615570828261509d565b91505060c083015184820360c086015261558a828261510c565b91505060e083015184820360e08601526155a482826151dd565b91505061010080840151858303828701526155bf8382615311565b9695505050505050565b600082516155db818460208701615c98565b9190910192915050565b60006001600160a01b038086168352808516602084015250606060408301526156116060830184615060565b95945050505050565b6001600160a01b0383168152608081016112966020830184805163ffffffff90811683526020808301516001600160a01b03169084015260409182015116910152565b6000606082016001600160a01b0386168352602067ffffffffffffffff8616818501526060604085015281855180845260808601915060808160051b8701019350828701855b828110156156d157607f198887030184526156bf868351615311565b955092840192908401906001016156a3565b50939998505050505050505050565b6060815260006156f3606083018661509d565b8281036020840152615705818661510c565b905082810360408401526155bf81856151dd565b60006020808301818452808551808352604092508286019150828160051b870101848801865b838110156157de57888303603f19018552815180516001600160a01b0390811685528882015160608a870181905281519087018190526080870192918b0191908c905b808210156157b05783518051841686528d015160070b8d860152938b0193928c019260019190910190615782565b505050509087015184820385890152906157ca8183615189565b96890196945050509086019060010161573f565b509098975050505050505050565b828152608081016112966020830184805163ffffffff90811683526020808301516001600160a01b03169084015260409182015116910152565b8281526040602082015260006111d5604083018461533d565b8281526040602082015260006111d5604083018461546f565b8281526040602082015260006111d560408301846154e8565b83815267ffffffffffffffff831660208201526060604082015260006156116060830184615060565b8460070b81526080602082015260006158b6608083018661509d565b82810360408401526158c8818661510c565b905082810360608401526158dc81856151dd565b979650505050505050565b606081016109d58284805163ffffffff90811683526020808301516001600160a01b03169084015260409182015116910152565b602081526000611296602083018461533d565b602081526000611296602083018461536c565b606081526000615954606083018661536c565b60208301949094525060400152919050565b60a08152600061597960a083018861536c565b8660208401528560408401528281036060840152615997818661509d565b905082810360808401526159ab818561510c565b98975050505050505050565b602081526000611296602083018461546f565b60208152600061129660208301846154e8565b67ffffffffffffffff831681526040602082015260006111d56040830184615060565b60405160a0810167ffffffffffffffff81118282101715615a2357615a23615d35565b60405290565b60405160c0810167ffffffffffffffff81118282101715615a2357615a23615d35565b6040516060810167ffffffffffffffff81118282101715615a2357615a23615d35565b6040805190810167ffffffffffffffff81118282101715615a2357615a23615d35565b604051610120810167ffffffffffffffff81118282101715615a2357615a23615d35565b604051601f8201601f1916810167ffffffffffffffff81118282101715615adf57615adf615d35565b604052919050565b600067ffffffffffffffff821115615b0157615b01615d35565b5060051b60200190565b600067ffffffffffffffff821115615b2557615b25615d35565b50601f01601f191660200190565b6000615b41613f2f84615ae7565b808482526020808301925084368760051b87011115615b5e578485fd5b845b87811015615c8c57813567ffffffffffffffff80821115615b7f578788fd5b818901915060608236031215615b93578788fd5b615b9b615a4c565b8235615ba681615d4b565b81528286013582811115615bb857898afd5b830136601f820112615bc857898afd5b8035615bd6613f2f82615ae7565b81815288810190838a0136600685901b86018c011115615bf4578d8efd5b8d94505b83851015615c49576040808236031215615c10578e8ffd5b615c18615a6f565b8235615c2381615d4b565b8152828d0135615c3281615d71565b818e0152845260019590950194928b019201615bf8565b50848a01525060409150508381013583811115615c64578a8bfd5b615c70368287016140c3565b9183019190915250875250509382019390820190600101615b60565b50919695505050505050565b60005b83811015615cb3578181015183820152602001615c9b565b83811115615cc2576000848401525b50505050565b600181811c90821680615cdc57607f821691505b60208210811415615cfd57634e487b7160e01b600052602260045260246000fd5b50919050565b60008160070b677fffffffffffffff19811415615d2e57634e487b7160e01b82526011600452602482fd5b9003919050565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114615d6057600080fd5b50565b8015158114615d6057600080fd5b8060070b8114615d6057600080fd5b63ffffffff81168114615d6057600080fd5b67ffffffffffffffff81168114615d6057600080fdfe90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aaa2646970667358221220add164a69fb3649d7787cd01cf3367f3be73142d2ec952baba16ed091764156d64736f6c63430008040033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/packages/server/tests/contracts/BaseHTS.sol b/packages/server/tests/contracts/BaseHTS.sol index f1b5791ee5..12ac7b5c14 100644 --- a/packages/server/tests/contracts/BaseHTS.sol +++ b/packages/server/tests/contracts/BaseHTS.sol @@ -32,6 +32,8 @@ contract BaseHTS is FeeHelper { event TokenDefaultKycStatus(bool defaultKycStatus); event KycGranted(bool kycGranted); event TokenExpiryInfo(IHederaTokenService.Expiry expiryInfo); + event IsToken(bool isToken); + event TokenType(int32 tokenType); function createFungibleTokenPublic( address treasury @@ -271,7 +273,7 @@ contract BaseHTS is FeeHelper { function freezeTokenPublic(address token, address account) public returns (int responseCode) { responseCode = HederaTokenService.freezeToken(token, account); emit ResponseCode(responseCode); - if(responseCode != HederaResponseCodes.SUCCESS) { + if (responseCode != HederaResponseCodes.SUCCESS) { revert(); } } @@ -279,7 +281,7 @@ contract BaseHTS is FeeHelper { function unfreezeTokenPublic(address token, address account) public returns (int responseCode) { responseCode = HederaTokenService.unfreezeToken(token, account); emit ResponseCode(responseCode); - if(responseCode != HederaResponseCodes.SUCCESS) { + if (responseCode != HederaResponseCodes.SUCCESS) { revert(); } } @@ -287,7 +289,7 @@ contract BaseHTS is FeeHelper { function isFrozenPublic(address token, address account) public returns (int responseCode, bool frozen) { (responseCode, frozen) = HederaTokenService.isFrozen(token, account); emit ResponseCode(responseCode); - if(responseCode != HederaResponseCodes.SUCCESS) { + if (responseCode != HederaResponseCodes.SUCCESS) { revert(); } emit Frozen(frozen); @@ -369,7 +371,7 @@ contract BaseHTS is FeeHelper { emit ResponseCode(responseCode); - if(responseCode != HederaResponseCodes.SUCCESS) { + if (responseCode != HederaResponseCodes.SUCCESS) { revert(); } @@ -390,45 +392,67 @@ contract BaseHTS is FeeHelper { emit ResponseCode(responseCode); - if(responseCode != HederaResponseCodes.SUCCESS) { + if (responseCode != HederaResponseCodes.SUCCESS) { revert(); } emit TokenDefaultKycStatus(defaultKycStatus); } - function isKycPublic(address token, address account)external returns (int64 responseCode, bool kycGranted){ + function isKycPublic(address token, address account) external returns (int64 responseCode, bool kycGranted){ (responseCode, kycGranted) = this.isKyc(token, account); emit ResponseCode(responseCode); - if(responseCode != HederaResponseCodes.SUCCESS) { + if (responseCode != HederaResponseCodes.SUCCESS) { revert(); } emit KycGranted(kycGranted); } - function grantTokenKycPublic(address token, address account)external returns (int64 responseCode){ + function grantTokenKycPublic(address token, address account) external returns (int64 responseCode){ (responseCode) = this.grantTokenKyc(token, account); emit ResponseCode(responseCode); - if(responseCode != HederaResponseCodes.SUCCESS) { + if (responseCode != HederaResponseCodes.SUCCESS) { revert(); } } - function revokeTokenKycPublic(address token, address account)external returns (int64 responseCode){ + function revokeTokenKycPublic(address token, address account) external returns (int64 responseCode){ (responseCode) = this.revokeTokenKyc(token, account); emit ResponseCode(responseCode); - if(responseCode != HederaResponseCodes.SUCCESS) { + if (responseCode != HederaResponseCodes.SUCCESS) { revert(); } } + function isTokenPublic(address token) public returns (int64 responseCode, bool isTokenFlag) { + (responseCode, isTokenFlag) = HederaTokenService.isToken(token); + emit ResponseCode(responseCode); + + if (responseCode != HederaResponseCodes.SUCCESS) { + revert(); + } + + emit IsToken(isTokenFlag); + } + + function getTokenTypePublic(address token) public returns (int64 responseCode, int32 tokenType) { + (responseCode, tokenType) = HederaTokenService.getTokenType(token); + emit ResponseCode(responseCode); + + if (responseCode != HederaResponseCodes.SUCCESS) { + revert(); + } + + emit TokenType(tokenType); + } + function getTokenExpiryInfoPublic(address token)external returns (int responseCode, IHederaTokenService.Expiry memory expiryInfo){ (responseCode, expiryInfo) = this.getTokenExpiryInfo(token); @@ -450,4 +474,4 @@ contract BaseHTS is FeeHelper { revert(); } } -} \ No newline at end of file +} diff --git a/packages/server/tests/contracts/FeeHelper.json b/packages/server/tests/contracts/FeeHelper.json index 5fc885d922..65c8f0575a 100644 --- a/packages/server/tests/contracts/FeeHelper.json +++ b/packages/server/tests/contracts/FeeHelper.json @@ -3,6 +3,100 @@ "contractName": "FeeHelper", "sourceName": "contracts/FeeHelper.sol", "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getTokenExpiryInfo", + "outputs": [ + { + "internalType": "int256", + "name": "responseCode", + "type": "int256" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "second", + "type": "uint32" + }, + { + "internalType": "address", + "name": "autoRenewAccount", + "type": "address" + }, + { + "internalType": "uint32", + "name": "autoRenewPeriod", + "type": "uint32" + } + ], + "internalType": "struct IHederaTokenService.Expiry", + "name": "expiryInfo", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantTokenKyc", + "outputs": [ + { + "internalType": "int64", + "name": "responseCode", + "type": "int64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "isKyc", + "outputs": [ + { + "internalType": "int64", + "name": "responseCode", + "type": "int64" + }, + { + "internalType": "bool", + "name": "kycGranted", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -22,6 +116,30 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeTokenKyc", + "outputs": [ + { + "internalType": "int64", + "name": "responseCode", + "type": "int64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -40,6 +158,47 @@ ], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "second", + "type": "uint32" + }, + { + "internalType": "address", + "name": "autoRenewAccount", + "type": "address" + }, + { + "internalType": "uint32", + "name": "autoRenewPeriod", + "type": "uint32" + } + ], + "internalType": "struct IHederaTokenService.Expiry", + "name": "expiryInfo", + "type": "tuple" + } + ], + "name": "updateTokenExpiryInfo", + "outputs": [ + { + "internalType": "int256", + "name": "responseCode", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" } ], "bytecode": "0x", diff --git a/packages/server/tests/contracts/HederaTokenService.sol b/packages/server/tests/contracts/HederaTokenService.sol index 15b7a60b1a..107fbfd2a0 100644 --- a/packages/server/tests/contracts/HederaTokenService.sol +++ b/packages/server/tests/contracts/HederaTokenService.sol @@ -30,7 +30,7 @@ abstract contract HederaTokenService is HederaResponseCodes { /// Initiates a Token Transfer /// @param tokenTransfers the list of transfers to do /// @return responseCode The response code for the status of the request. SUCCESS is 22. - function cryptoTransfer(IHederaTokenService.TokenTransferList[] memory tokenTransfers) internal + function cryptoTransfer(IHederaTokenService.TokenTransferList[] memory tokenTransfers) internal returns (int responseCode) { (bool success, bytes memory result) = precompileAddress.call( @@ -157,7 +157,7 @@ abstract contract HederaTokenService is HederaResponseCodes { uint64 initialTotalSupply, uint32 decimals) nonEmptyExpiry(token) internal returns (int responseCode, address tokenAddress) { - (bool success, bytes memory result) = precompileAddress.call{value: msg.value}( + (bool success, bytes memory result) = precompileAddress.call{value : msg.value}( abi.encodeWithSelector(IHederaTokenService.createFungibleToken.selector, token, initialTotalSupply, decimals)); @@ -181,7 +181,7 @@ abstract contract HederaTokenService is HederaResponseCodes { IHederaTokenService.FixedFee[] memory fixedFees, IHederaTokenService.FractionalFee[] memory fractionalFees) nonEmptyExpiry(token) internal returns (int responseCode, address tokenAddress) { - (bool success, bytes memory result) = precompileAddress.call{value: msg.value}( + (bool success, bytes memory result) = precompileAddress.call{value : msg.value}( abi.encodeWithSelector(IHederaTokenService.createFungibleTokenWithCustomFees.selector, token, initialTotalSupply, decimals, fixedFees, fractionalFees)); (responseCode, tokenAddress) = success ? abi.decode(result, (int32, address)) : (HederaResponseCodes.UNKNOWN, address(0)); @@ -193,7 +193,7 @@ abstract contract HederaTokenService is HederaResponseCodes { /// @return tokenAddress the created token's address function createNonFungibleToken(IHederaTokenService.HederaToken memory token) nonEmptyExpiry(token) internal returns (int responseCode, address tokenAddress) { - (bool success, bytes memory result) = precompileAddress.call{value: msg.value}( + (bool success, bytes memory result) = precompileAddress.call{value : msg.value}( abi.encodeWithSelector(IHederaTokenService.createNonFungibleToken.selector, token)); (responseCode, tokenAddress) = success ? abi.decode(result, (int32, address)) : (HederaResponseCodes.UNKNOWN, address(0)); } @@ -209,7 +209,7 @@ abstract contract HederaTokenService is HederaResponseCodes { IHederaTokenService.FixedFee[] memory fixedFees, IHederaTokenService.RoyaltyFee[] memory royaltyFees) nonEmptyExpiry(token) internal returns (int responseCode, address tokenAddress) { - (bool success, bytes memory result) = precompileAddress.call{value: msg.value}( + (bool success, bytes memory result) = precompileAddress.call{value : msg.value}( abi.encodeWithSelector(IHederaTokenService.createNonFungibleTokenWithCustomFees.selector, token, fixedFees, royaltyFees)); (responseCode, tokenAddress) = success ? abi.decode(result, (int32, address)) : (HederaResponseCodes.UNKNOWN, address(0)); @@ -328,10 +328,10 @@ abstract contract HederaTokenService is HederaResponseCodes { /// @param account The account address associated with the token /// @return responseCode The response code for the status of the request. SUCCESS is 22. /// @return frozen True if `account` is frozen for `token` - function isFrozen(address token, address account)internal returns (int64 responseCode, bool frozen){ + function isFrozen(address token, address account) internal returns (int64 responseCode, bool frozen){ (bool success, bytes memory result) = precompileAddress.call( abi.encodeWithSelector(IHederaTokenService.isFrozen.selector, token, account)); - (responseCode, frozen) = success ? abi.decode(result, (int32,bool)) : (HederaResponseCodes.UNKNOWN,false); + (responseCode, frozen) = success ? abi.decode(result, (int32, bool)) : (HederaResponseCodes.UNKNOWN, false); } /// Query if token account has kyc granted @@ -339,10 +339,10 @@ abstract contract HederaTokenService is HederaResponseCodes { /// @param account The account address associated with the token /// @return responseCode The response code for the status of the request. SUCCESS is 22. /// @return kycGranted True if `account` has kyc granted for `token` - function isKyc(address token, address account)external returns (int64 responseCode, bool kycGranted){ + function isKyc(address token, address account) external returns (int64 responseCode, bool kycGranted){ (bool success, bytes memory result) = precompileAddress.call( abi.encodeWithSelector(IHederaTokenService.isKyc.selector, token, account)); - (responseCode, kycGranted) = success ? abi.decode(result, (int32,bool)) : (HederaResponseCodes.UNKNOWN,false); + (responseCode, kycGranted) = success ? abi.decode(result, (int32, bool)) : (HederaResponseCodes.UNKNOWN, false); } /// Operation to freeze token account @@ -359,7 +359,7 @@ abstract contract HederaTokenService is HederaResponseCodes { /// @param token The token address /// @param account The account address to be unfrozen /// @return responseCode The response code for the status of the request. SUCCESS is 22. - function unfreezeToken(address token, address account)internal returns (int64 responseCode){ + function unfreezeToken(address token, address account) internal returns (int64 responseCode){ (bool success, bytes memory result) = precompileAddress.call( abi.encodeWithSelector(IHederaTokenService.unfreezeToken.selector, token, account)); (responseCode) = success ? abi.decode(result, (int32)) : HederaResponseCodes.UNKNOWN; @@ -369,7 +369,7 @@ abstract contract HederaTokenService is HederaResponseCodes { /// @param token The token address /// @param account The account address to grant kyc /// @return responseCode The response code for the status of the request. SUCCESS is 22. - function grantTokenKyc(address token, address account)external returns (int64 responseCode){ + function grantTokenKyc(address token, address account) external returns (int64 responseCode){ (bool success, bytes memory result) = precompileAddress.call( abi.encodeWithSelector(IHederaTokenService.grantTokenKyc.selector, token, account)); (responseCode) = success ? abi.decode(result, (int32)) : HederaResponseCodes.UNKNOWN; @@ -379,7 +379,7 @@ abstract contract HederaTokenService is HederaResponseCodes { /// @param token The token address /// @param account The account address to revoke kyc /// @return responseCode The response code for the status of the request. SUCCESS is 22. - function revokeTokenKyc(address token, address account)external returns (int64 responseCode){ + function revokeTokenKyc(address token, address account) external returns (int64 responseCode){ (bool success, bytes memory result) = precompileAddress.call( abi.encodeWithSelector(IHederaTokenService.revokeTokenKyc.selector, token, account)); (responseCode) = success ? abi.decode(result, (int32)) : HederaResponseCodes.UNKNOWN; @@ -556,6 +556,26 @@ abstract contract HederaTokenService is HederaResponseCodes { (responseCode) = success ? abi.decode(result, (int32)) : HederaResponseCodes.UNKNOWN; } + /// Query if valid token found for the given address + /// @param token The token address + /// @return responseCode The response code for the status of the request. SUCCESS is 22. + /// @return isTokenFlag True if valid token found for the given address + function isToken(address token) internal returns (int64 responseCode, bool isTokenFlag) { + (bool success, bytes memory result) = precompileAddress.call( + abi.encodeWithSelector(IHederaTokenService.isToken.selector, token)); + (responseCode, isTokenFlag) = success ? abi.decode(result, (int32, bool)) : (HederaResponseCodes.UNKNOWN, false); + } + + /// Query to return the token type for a given address + /// @param token The token address + /// @return responseCode The response code for the status of the request. SUCCESS is 22. + /// @return tokenType the token type. 0 is FUNGIBLE_COMMON, 1 is NON_FUNGIBLE_UNIQUE, -1 is UNRECOGNIZED + function getTokenType(address token) internal returns (int64 responseCode, int32 tokenType) { + (bool success, bytes memory result) = precompileAddress.call( + abi.encodeWithSelector(IHederaTokenService.getTokenType.selector, token)); + (responseCode, tokenType) = success ? abi.decode(result, (int32, int32)) : (HederaResponseCodes.UNKNOWN, - 1); + } + /// Operation to get token expiry info /// @param token The token address /// @return responseCode The response code for the status of the request. SUCCESS is 22. diff --git a/packages/server/tests/contracts/IHederaTokenService.json b/packages/server/tests/contracts/IHederaTokenService.json index dafdcaebc7..e9dc922377 100644 --- a/packages/server/tests/contracts/IHederaTokenService.json +++ b/packages/server/tests/contracts/IHederaTokenService.json @@ -2086,6 +2086,30 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getTokenType", + "outputs": [ + { + "internalType": "int64", + "name": "responseCode", + "type": "int64" + }, + { + "internalType": "int32", + "name": "tokenType", + "type": "int32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -2202,6 +2226,30 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "isToken", + "outputs": [ + { + "internalType": "int64", + "name": "responseCode", + "type": "int64" + }, + { + "internalType": "bool", + "name": "isTokenFlag", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { diff --git a/packages/server/tests/contracts/IHederaTokenService.sol b/packages/server/tests/contracts/IHederaTokenService.sol index da5786b88b..643b5fc631 100644 --- a/packages/server/tests/contracts/IHederaTokenService.sol +++ b/packages/server/tests/contracts/IHederaTokenService.sol @@ -443,8 +443,8 @@ interface IHederaTokenService { /// @return responseCode The response code for the status of the request. SUCCESS is 22. /// @return kycGranted True if `account` has kyc granted for `token` function isKyc(address token, address account) - external - returns (int64 responseCode, bool kycGranted); + external + returns (int64 responseCode, bool kycGranted); /// Operation to freeze token account /// @param token The token address @@ -467,16 +467,16 @@ interface IHederaTokenService { /// @param account The account address to grant kyc /// @return responseCode The response code for the status of the request. SUCCESS is 22. function grantTokenKyc(address token, address account) - external - returns (int64 responseCode); + external + returns (int64 responseCode); /// Operation to revoke kyc to token account /// @param token The token address /// @param account The account address to revoke kyc /// @return responseCode The response code for the status of the request. SUCCESS is 22. function revokeTokenKyc(address token, address account) - external - returns (int64 responseCode); + external + returns (int64 responseCode); /// Query token custom fees /// @param token The token address to check @@ -617,4 +617,16 @@ interface IHederaTokenService { /// @param token The token address /// @return responseCode The response code for the status of the request. SUCCESS is 22. function updateTokenExpiryInfo(address token, Expiry memory expiryInfo) external returns (int responseCode); + + /// Query if valid token found for the given address + /// @param token The token address + /// @return responseCode The response code for the status of the request. SUCCESS is 22. + /// @return isTokenFlag True if valid token found for the given address + function isToken(address token) external returns (int64 responseCode, bool isTokenFlag); + + /// Query to return the token type for a given address + /// @param token The token address + /// @return responseCode The response code for the status of the request. SUCCESS is 22. + /// @return tokenType the token type. 0 is FUNGIBLE_COMMON, 1 is NON_FUNGIBLE_UNIQUE, -1 is UNRECOGNIZED + function getTokenType(address token) external returns (int64 responseCode, int32 tokenType); } diff --git a/packages/server/tests/contracts/KeyHelper.json b/packages/server/tests/contracts/KeyHelper.json index b8861022e5..eeef7778f9 100644 --- a/packages/server/tests/contracts/KeyHelper.json +++ b/packages/server/tests/contracts/KeyHelper.json @@ -3,6 +3,100 @@ "contractName": "KeyHelper", "sourceName": "contracts/KeyHelper.sol", "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getTokenExpiryInfo", + "outputs": [ + { + "internalType": "int256", + "name": "responseCode", + "type": "int256" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "second", + "type": "uint32" + }, + { + "internalType": "address", + "name": "autoRenewAccount", + "type": "address" + }, + { + "internalType": "uint32", + "name": "autoRenewPeriod", + "type": "uint32" + } + ], + "internalType": "struct IHederaTokenService.Expiry", + "name": "expiryInfo", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantTokenKyc", + "outputs": [ + { + "internalType": "int64", + "name": "responseCode", + "type": "int64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "isKyc", + "outputs": [ + { + "internalType": "int64", + "name": "responseCode", + "type": "int64" + }, + { + "internalType": "bool", + "name": "kycGranted", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -22,6 +116,30 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeTokenKyc", + "outputs": [ + { + "internalType": "int64", + "name": "responseCode", + "type": "int64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -40,6 +158,47 @@ ], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "second", + "type": "uint32" + }, + { + "internalType": "address", + "name": "autoRenewAccount", + "type": "address" + }, + { + "internalType": "uint32", + "name": "autoRenewPeriod", + "type": "uint32" + } + ], + "internalType": "struct IHederaTokenService.Expiry", + "name": "expiryInfo", + "type": "tuple" + } + ], + "name": "updateTokenExpiryInfo", + "outputs": [ + { + "internalType": "int256", + "name": "responseCode", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" } ], "bytecode": "0x",