@allorc/a423-sdk 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,24 @@
1
+ // Dry-run by default. Explicit --broadcast deploys; --verify submits published sources to Sourcify.
2
+ import fs from 'node:fs/promises';
3
+ import {JsonRpcProvider,Wallet,ContractFactory,getAddress} from 'ethers';
4
+ import escrow from '../src/escrow/index.cjs';
5
+ const args=new Set(process.argv.slice(2));
6
+ const chainId=Number(process.env.A423_CHAIN_ID),token=getAddress(process.env.A423_TOKEN_ADDRESS);
7
+ if(!Number.isSafeInteger(chainId)||chainId<=0)throw Error('Explicit A423_CHAIN_ID required');
8
+ const provider=new JsonRpcProvider(process.env.A423_RPC_URL);if(Number((await provider.getNetwork()).chainId)!==chainId)throw Error('RPC chain mismatch');
9
+ if(await provider.getCode(token)==='0x')throw Error('Token has no code');
10
+ if(!args.has('--broadcast')){console.log(JSON.stringify({dryRun:true,chainId,token,bytecodeBytes:(escrow.ESCROW_BYTECODE.length-2)/2}));process.exit(0);}
11
+ if(!process.env.A423_DEPLOYER_KEY)throw Error('A423_DEPLOYER_KEY required for explicit deployment');
12
+ const signer=new Wallet(process.env.A423_DEPLOYER_KEY,provider),factory=new ContractFactory(escrow.ESCROW_ABI,escrow.ESCROW_BYTECODE,signer);
13
+ const contract=await factory.deploy(token);const receipt=await contract.deploymentTransaction().wait(Number(process.env.A423_CONFIRMATIONS||1));
14
+ const address=await contract.getAddress();const result={chainId,token,address,transaction:receipt.hash,verification:'not_requested'};
15
+ await fs.writeFile(process.env.A423_DEPLOYMENT_FILE||'a423-deployment.json',JSON.stringify(result,null,2)+'\n',{mode:0o600});
16
+ if(args.has('--verify')){
17
+ const stdJsonInput=JSON.parse(await fs.readFile(new URL('../contracts/standard-input.json',import.meta.url),'utf8'));
18
+ const artifact=JSON.parse(await fs.readFile(new URL('../src/escrow/artifact.json',import.meta.url),'utf8'));
19
+ const response=await fetch(`https://sourcify.dev/server/v2/verify/${chainId}/${address}`,{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({stdJsonInput,compilerVersion:artifact.compiler.split('.Emscripten')[0],contractIdentifier:'A423Escrow.sol:A423Escrow',creationTransactionHash:receipt.hash}),redirect:'error',signal:AbortSignal.timeout(30000)});
20
+ const verification=await response.json();if(!response.ok)throw Error('Deployed, but source verification submission failed: '+response.status);
21
+ result.verification='submitted';result.verificationRequest=verification;
22
+ await fs.writeFile(process.env.A423_DEPLOYMENT_FILE||'a423-deployment.json',JSON.stringify(result,null,2)+'\n',{mode:0o600});
23
+ }
24
+ console.log(JSON.stringify(result));
@@ -0,0 +1,22 @@
1
+ // Opt-in operational loop; application config must explicitly supply signer approvals and execution callbacks.
2
+ import {pathToFileURL} from 'node:url';
3
+ import {setTimeout} from 'node:timers/promises';
4
+ import {watchEvidenceOnce,runMaintenanceOnce,enqueueRunningJobs,runExecutionOnce} from '../src/operations/index.mjs';
5
+ if(!process.env.A423_CONFIG_MODULE)throw Error('A423_CONFIG_MODULE required');
6
+ const {applicationOptions:app,workerOptions:worker}=await import(pathToFileURL(process.env.A423_CONFIG_MODULE).href);
7
+ if(!worker?.actorFor)throw Error('workerOptions.actorFor must explicitly delegate maintenance actors');
8
+ const controller=new AbortController();for(const signal of ['SIGINT','SIGTERM'])process.on(signal,()=>controller.abort());
9
+ while(!controller.signal.aborted){
10
+ try{
11
+ await watchEvidenceOnce({store:app.store,revalidate:app.revalidate});
12
+ if(worker.index)await worker.index();
13
+ if(worker.replaceFees)await worker.replaceFees();
14
+ const maintenance=await runMaintenanceOnce({workflow:app.workflow,store:app.store,actorFor:worker.actorFor,allowExecute:worker.allowExecute===true});
15
+ for(const result of maintenance)if(result.error)console.error('A423 maintenance failed for job',result.id);
16
+ await enqueueRunningJobs({store:app.store,queue:app.queue});
17
+ if(worker.execute)await runExecutionOnce({workflow:app.workflow,queue:app.queue,execute:worker.execute,beforeExecute:worker.beforeExecute});
18
+ if(worker.webhooks){await worker.webhooks.project(app.store);for(let i=0;i<10;i++)if(!await worker.webhooks.deliverOne())break;}
19
+ if(worker.authority)await worker.authority.pruneChallenges();
20
+ }catch(error){console.error('A423 worker tick failed:',error.code||error.name);}
21
+ try{await setTimeout(5000,undefined,{signal:controller.signal});}catch{}
22
+ }
@@ -0,0 +1,81 @@
1
+ 'use strict';
2
+ const {createPublicKey,sign,verify,randomBytes,createHash}=require('node:crypto');
3
+ const encode=x=>Buffer.from(JSON.stringify(x)).toString('base64url');
4
+ const fingerprint=key=>createHash('sha256').update(createPublicKey(key).export({type:'spki',format:'der'})).digest('hex');
5
+ function requireValue(ok,message){if(!ok)throw Error(message);}
6
+ function publicKey(pem){const key=createPublicKey(pem);requireValue(key.asymmetricKeyType==='ed25519','Ed25519 public key required');return key;}
7
+ function createAuthority({issuer,audience,privateKey,kv,credentialTtlSeconds=3600,challengeTtlSeconds=120,now=()=>Date.now()}={}){
8
+ requireValue(issuer&&audience&&privateKey&&kv,'Authority configuration required');publicKey(createPublicKey(privateKey).export({type:'spki',format:'pem'}));
9
+ requireValue(Number.isInteger(credentialTtlSeconds)&&credentialTtlSeconds>0&&credentialTtlSeconds<=86400,'Credential TTL must be 1..86400 seconds');
10
+ requireValue(Number.isInteger(challengeTtlSeconds)&&challengeTtlSeconds>0&&challengeTtlSeconds<=600,'Challenge TTL must be 1..600 seconds');
11
+ const ns='authority:'+issuer+':'+audience;
12
+ const read=(kind,id)=>kv.get(ns+':'+kind,id),put=(kind,id,v)=>kv.put(ns+':'+kind,id,v);
13
+ const safe=x=>requireValue(typeof x==='string'&&/^[A-Za-z0-9:_-]{1,256}$/.test(x),'Invalid identity');
14
+ async function records(agentId){const agent=await read('agents',agentId);requireValue(agent&&!agent.revoked,'Unknown/revoked agent');const org=await read('organizations',agent.organization);requireValue(org&&!org.revoked,'Unknown/revoked organization');return {agent,org};}
15
+ const registration=({organization,agentId,publicKey: key,scopes})=>({version:'a423.enrollment.v1',issuer,audience,organization,agent_id:agentId,key_fingerprint:fingerprint(key),scopes:[...scopes].sort()});
16
+ return {
17
+ publicKey:createPublicKey(privateKey).export({type:'spki',format:'pem'}),
18
+ registration,
19
+ async isActive(agentId){try{await records(agentId);return true;}catch{return false;}},
20
+ /** Administrative capability: perform real-world approval outside this module before calling. */
21
+ async registerOrganization({id,name,publicKey:key}){safe(id);requireValue(typeof name==='string'&&name.trim()&&name.length<=256,'Organization name required');publicKey(key);requireValue(await kv.create(ns+':organizations',id,{id,name,publicKey:key,revoked:false}),'Organization already registered');},
22
+ async revokeOrganization(id){const org=await read('organizations',id);requireValue(org,'Unknown organization');await put('organizations',id,{...org,revoked:true});},
23
+ async registerAgent({organization,agentId,publicKey:key,scopes=['workflow'],organizationSignature}){
24
+ safe(agentId);const org=await read('organizations',organization);requireValue(org&&!org.revoked,'Organization not approved');publicKey(key);
25
+ requireValue(Array.isArray(scopes)&&scopes.length>0&&scopes.length<=64&&scopes.every(s=>typeof s==='string'&&/^[a-z0-9:_-]{1,128}$/.test(s)),'Invalid scopes');
26
+ const statement=registration({organization,agentId,publicKey:key,scopes});
27
+ requireValue(verify(null,Buffer.from(JSON.stringify(statement)),publicKey(org.publicKey),Buffer.from(organizationSignature,'base64url')),'Invalid organization enrollment signature');
28
+ requireValue(await kv.create(ns+':agents',agentId,{id:agentId,organization,publicKey:key,scopes:[...new Set(scopes)],revoked:false}),'Agent already registered');
29
+ },
30
+ async revokeAgent(agentId){const agent=await read('agents',agentId);requireValue(agent,'Unknown agent');await put('agents',agentId,{...agent,revoked:true});},
31
+ async challenge(agentId){const {agent}=await records(agentId);const id=randomBytes(32).toString('base64url');const statement={version:'a423.challenge.v1',issuer,audience,id,agent_id:agentId,key_fingerprint:fingerprint(agent.publicKey),expires_at:Math.floor(now()/1000)+challengeTtlSeconds};await kv.create(ns+':challenges',id,statement);return statement;},
32
+ async exchange({challengeId,signature}){
33
+ safe(challengeId);const challenge=await kv.take(ns+':challenges',challengeId);requireValue(challenge&&challenge.expires_at>Math.floor(now()/1000),'Challenge expired, consumed or unknown');const {agent}=await records(challenge.agent_id);
34
+ requireValue(verify(null,Buffer.from(JSON.stringify(challenge)),publicKey(agent.publicKey),Buffer.from(signature,'base64url')),'Invalid challenge signature');
35
+ const issued=Math.floor(now()/1000);const payload={version:'a423.credential.v1',iss:issuer,aud:audience,sub:agent.id,org:agent.organization,key_fingerprint:fingerprint(agent.publicKey),scopes:agent.scopes,iat:issued,exp:issued+credentialTtlSeconds,jti:randomBytes(24).toString('base64url')};const content=encode(payload);return {credential:content+'.'+sign(null,Buffer.from(content),privateKey).toString('base64url'),expires_at:payload.exp};
36
+ },
37
+ async verifyCredential(credential,{scope='workflow'}={}){
38
+ requireValue(typeof credential==='string'&&credential.length<=16000,'Invalid credential');const parts=credential.split('.');requireValue(parts.length===2,'Invalid credential encoding');
39
+ requireValue(verify(null,Buffer.from(parts[0]),createPublicKey(privateKey),Buffer.from(parts[1],'base64url')),'Invalid authority signature');
40
+ const p=JSON.parse(Buffer.from(parts[0],'base64url').toString('utf8'));const time=Math.floor(now()/1000);
41
+ requireValue(p.version==='a423.credential.v1'&&p.iss===issuer&&p.aud===audience&&Number.isSafeInteger(p.exp)&&Number.isSafeInteger(p.iat)&&p.iat<=time&&p.exp>time&&p.exp-p.iat<=credentialTtlSeconds,'Expired or invalid credential');
42
+ const {agent}=await records(p.sub);requireValue(p.org===agent.organization&&p.key_fingerprint===fingerprint(agent.publicKey)&&p.scopes.includes(scope)&&agent.scopes.includes(scope),'Credential binding/scope mismatch');return p;
43
+ },
44
+ async pruneChallenges(){let removed=0;for(const r of await kv.list(ns+':challenges'))if(r.value.expires_at<=Math.floor(now()/1000)){await kv.take(ns+':challenges',r.id);removed++;}return removed;}
45
+ };
46
+ }
47
+ function createCredentialAuthenticator({authority,scope='workflow'}={}){return async request=>{const h=request.headers.get('authorization')||'';if(!h.startsWith('Bearer '))return null;try{return (await authority.verifyCredential(h.slice(7),{scope})).sub;}catch{return null;}};}
48
+ /** Renew using a fresh proof of possession. Never prolong a credential from a bearer token alone. */
49
+ function createCredentialProvider({agentId,challenge,exchange,signChallenge,refreshBeforeSeconds=60,now=()=>Date.now()}={}){
50
+ let current=null,inflight=null;
51
+ return async()=>{
52
+ if(current&&current.expires_at-Math.floor(now()/1000)>refreshBeforeSeconds)return current.credential;
53
+ if(!inflight)inflight=(async()=>{const c=await challenge(agentId);const signature=await signChallenge(Buffer.from(JSON.stringify(c)));current=await exchange({challengeId:c.id,signature});return current.credential;})().finally(()=>{inflight=null;});
54
+ return inflight;
55
+ };
56
+ }
57
+ module.exports={createAuthority,createCredentialAuthenticator,createCredentialProvider};
58
+ /** Public proof endpoints only. Administrative enrollment is deliberately not exposed. */
59
+ function createAuthorityHandler({authority,basePath='/api/a423-auth',allowRequest=async()=>false}={}){
60
+ return async request=>{
61
+ const path=new URL(request.url).pathname;
62
+ if(request.method!=='POST'||![basePath+'/challenge',basePath+'/exchange'].includes(path))return Response.json({error:'not found'},{status:404});
63
+ if(await allowRequest(request)!==true)return Response.json({error:'rate limit or policy denied'},{status:429});
64
+ try{if(!request.body||!(request.headers.get('content-type')||'').startsWith('application/json'))throw Error('JSON required');const reader=request.body.getReader();let size=0;const chunks=[];try{while(true){const {done,value}=await reader.read();if(done)break;size+=value.byteLength;if(size>16384){await reader.cancel();throw Error('Body too large');}chunks.push(Buffer.from(value));}}finally{reader.releaseLock();}const body=JSON.parse(Buffer.concat(chunks).toString('utf8'));
65
+ const result=path.endsWith('/challenge')?await authority.challenge(body.agent_id):await authority.exchange(body);
66
+ return Response.json(result,{headers:{'cache-control':'no-store'}});
67
+ }catch{return Response.json({error:'invalid proof or request'},{status:400});}
68
+ };
69
+ }
70
+ module.exports.createAuthorityHandler=createAuthorityHandler;
71
+ /** Receiver-side verification uses public trust roots and a revocation/status lookup, never the authority private key. */
72
+ function createCredentialVerifier({issuer,audience,publicKey:trustedKey,isActive,maxTtlSeconds=86400,now=()=>Date.now()}={}){
73
+ const key=publicKey(trustedKey);requireValue(typeof isActive==='function','Explicit revocation/status lookup required');
74
+ return async(credential,{scope='workflow'}={})=>{
75
+ requireValue(typeof credential==='string'&&credential.length<=16000,'Invalid credential');const parts=credential.split('.');requireValue(parts.length===2&&verify(null,Buffer.from(parts[0]),key,Buffer.from(parts[1],'base64url')),'Invalid authority signature');
76
+ const p=JSON.parse(Buffer.from(parts[0],'base64url').toString('utf8')),time=Math.floor(now()/1000);
77
+ requireValue(p.version==='a423.credential.v1'&&p.iss===issuer&&p.aud===audience&&Number.isSafeInteger(p.exp)&&Number.isSafeInteger(p.iat)&&p.iat<=time&&p.exp>time&&p.exp-p.iat<=maxTtlSeconds&&Array.isArray(p.scopes)&&p.scopes.includes(scope),'Expired or invalid credential');
78
+ requireValue(await isActive(p)===true,'Agent/organization revoked or unavailable');return p;
79
+ };
80
+ }
81
+ module.exports.createCredentialVerifier=createCredentialVerifier;
@@ -0,0 +1,24 @@
1
+ import type { KeyObject } from 'node:crypto';
2
+ import type { KeyValueStore } from '../storage/index.js';
3
+ export interface Challenge {version: string;issuer: string;audience: string;id: string;agent_id: string;key_fingerprint: string;expires_at: number}
4
+ export interface Credential {credential: string;expires_at: number}
5
+ export interface Enrollment {organization: string;agentId: string;publicKey: string;scopes: string[]}
6
+ export interface Authority {
7
+ publicKey: string;
8
+ isActive(agentId: string): Promise<boolean>;
9
+ registration(input: Enrollment): object;
10
+ registerOrganization(input: {id: string;name: string;publicKey: string}): Promise<void>;
11
+ revokeOrganization(id: string): Promise<void>;
12
+ registerAgent(input: Enrollment & {organizationSignature: string}): Promise<void>;
13
+ revokeAgent(id: string): Promise<void>;
14
+ challenge(agentId: string): Promise<Challenge>;
15
+ exchange(input: {challengeId: string;signature: string}): Promise<Credential>;
16
+ verifyCredential(token: string, options?: {scope?: string}): Promise<{sub: string;org: string;scopes: string[];exp: number;[key: string]: unknown}>;
17
+ pruneChallenges(): Promise<number>;
18
+ }
19
+ export function createAuthority(options: {issuer: string;audience: string;privateKey: string | KeyObject;kv: KeyValueStore;credentialTtlSeconds?: number;challengeTtlSeconds?: number;now?(): number}): Authority;
20
+ export function createCredentialAuthenticator(options: {authority: Pick<Authority,'verifyCredential'>;scope?: string}): (request: Request) => Promise<string | null>;
21
+ export function createCredentialProvider(options: {agentId: string;challenge(id: string): Promise<Challenge>;exchange(input: {challengeId: string;signature: string}): Promise<Credential>;signChallenge(bytes: Buffer): Promise<string>;refreshBeforeSeconds?: number;now?(): number}): () => Promise<string>;
22
+ export function createAuthorityHandler(options: {authority: Authority;basePath?: string;allowRequest?(request: Request): Promise<boolean>}): (request: Request) => Promise<Response>;
23
+
24
+ export function createCredentialVerifier(options: {issuer: string;audience: string;publicKey: string;isActive(payload: any): Promise<boolean>;maxTtlSeconds?: number;now?(): number}): Authority['verifyCredential'];
@@ -0,0 +1,2 @@
1
+ import api from './index.cjs';
2
+ export const { createAuthority, createCredentialAuthenticator, createCredentialProvider, createAuthorityHandler, createCredentialVerifier } = api;
@@ -0,0 +1,17 @@
1
+ 'use strict';
2
+ const {hashAgreement}=require('./workflow.cjs');
3
+ function check(ok,message){if(!ok)throw new TypeError(message);}
4
+ function settlementProposal(job,input){
5
+ const e=job.agreement?.terms.escrow;check(e&&hashAgreement(job.agreement.terms)===job.agreement.hash,'Valid escrow agreement required');
6
+ check(input&&typeof input.worker_amount==='string'&&/^(0|[1-9][0-9]*)$/.test(input.worker_amount),'worker_amount must be a nonnegative raw-unit decimal string');
7
+ const total=BigInt(e.amount),worker=BigInt(input.worker_amount);check(worker<=total,'Allocation exceeds escrow');
8
+ check(Number.isSafeInteger(input.expected_revision)&&input.expected_revision>=0&&input.expected_revision<Number.MAX_SAFE_INTEGER,'expected_revision required');
9
+ check(Number.isSafeInteger(input.expires_at)&&input.expires_at>0&&input.expires_at<=e.resolution_deadline,'Proposal expiry must respect original resolution deadline');
10
+ check(typeof input.reason==='string'&&input.reason.trim()&&input.reason.length<=4000,'Explain the proposed closing settlement');
11
+ const claims=input.claims||[];check(Array.isArray(claims)&&claims.length<=64,'At most 64 claims');
12
+ for(const claim of claims){check(claim&&['work','expense','other'].includes(claim.kind)&&typeof claim.description==='string'&&claim.description.trim()&&claim.description.length<=4000,'Invalid partial-work/expense claim');if(claim.amount!==undefined)check(typeof claim.amount==='string'&&/^(0|[1-9][0-9]*)$/.test(claim.amount),'Claim amount must use raw units');if(claim.evidence!==undefined)check(Array.isArray(claim.evidence)&&claim.evidence.length<=32&&claim.evidence.every(ref=>typeof ref==='string'&&ref.length>0&&ref.length<=2048),'Invalid evidence references');}
13
+ const payer=(total-worker).toString();if(input.payer_amount!==undefined)check(input.payer_amount===payer,'Amounts must equal remaining escrow');
14
+ const proposal={version:'a423.closing.v1',job_id:job.id,agreement_hash:job.agreement.hash,escrow_version:input.expected_revision+1,worker_amount:worker.toString(),payer_amount:payer,expires_at:input.expires_at,reason:input.reason,claims:structuredClone(claims),closes_job:true};
15
+ return {...proposal,proposal_hash:'0x'+hashAgreement(proposal)};
16
+ }
17
+ module.exports={settlementProposal};
@@ -189,6 +189,80 @@
189
189
  "name": "Settled",
190
190
  "type": "event"
191
191
  },
192
+ {
193
+ "anonymous": false,
194
+ "inputs": [
195
+ {
196
+ "indexed": true,
197
+ "internalType": "bytes32",
198
+ "name": "jobId",
199
+ "type": "bytes32"
200
+ },
201
+ {
202
+ "indexed": false,
203
+ "internalType": "uint64",
204
+ "name": "revision",
205
+ "type": "uint64"
206
+ },
207
+ {
208
+ "indexed": false,
209
+ "internalType": "bytes32",
210
+ "name": "proposalHash",
211
+ "type": "bytes32"
212
+ }
213
+ ],
214
+ "name": "SettlementAccepted",
215
+ "type": "event"
216
+ },
217
+ {
218
+ "anonymous": false,
219
+ "inputs": [
220
+ {
221
+ "indexed": true,
222
+ "internalType": "bytes32",
223
+ "name": "jobId",
224
+ "type": "bytes32"
225
+ },
226
+ {
227
+ "indexed": false,
228
+ "internalType": "uint64",
229
+ "name": "revision",
230
+ "type": "uint64"
231
+ },
232
+ {
233
+ "indexed": true,
234
+ "internalType": "address",
235
+ "name": "proposer",
236
+ "type": "address"
237
+ },
238
+ {
239
+ "indexed": false,
240
+ "internalType": "uint256",
241
+ "name": "workerAmount",
242
+ "type": "uint256"
243
+ },
244
+ {
245
+ "indexed": false,
246
+ "internalType": "uint256",
247
+ "name": "payerAmount",
248
+ "type": "uint256"
249
+ },
250
+ {
251
+ "indexed": false,
252
+ "internalType": "bytes32",
253
+ "name": "proposalHash",
254
+ "type": "bytes32"
255
+ },
256
+ {
257
+ "indexed": false,
258
+ "internalType": "uint64",
259
+ "name": "expiresAt",
260
+ "type": "uint64"
261
+ }
262
+ ],
263
+ "name": "SettlementProposed",
264
+ "type": "event"
265
+ },
192
266
  {
193
267
  "anonymous": false,
194
268
  "inputs": [
@@ -227,6 +301,19 @@
227
301
  "name": "Verified",
228
302
  "type": "event"
229
303
  },
304
+ {
305
+ "inputs": [],
306
+ "name": "SETTLEMENT_TYPEHASH",
307
+ "outputs": [
308
+ {
309
+ "internalType": "bytes32",
310
+ "name": "",
311
+ "type": "bytes32"
312
+ }
313
+ ],
314
+ "stateMutability": "view",
315
+ "type": "function"
316
+ },
230
317
  {
231
318
  "inputs": [],
232
319
  "name": "TERMS_TYPEHASH",
@@ -240,6 +327,29 @@
240
327
  "stateMutability": "view",
241
328
  "type": "function"
242
329
  },
330
+ {
331
+ "inputs": [
332
+ {
333
+ "internalType": "bytes32",
334
+ "name": "id",
335
+ "type": "bytes32"
336
+ },
337
+ {
338
+ "internalType": "uint64",
339
+ "name": "revision",
340
+ "type": "uint64"
341
+ },
342
+ {
343
+ "internalType": "bytes32",
344
+ "name": "proposalHash",
345
+ "type": "bytes32"
346
+ }
347
+ ],
348
+ "name": "acceptSettlement",
349
+ "outputs": [],
350
+ "stateMutability": "nonpayable",
351
+ "type": "function"
352
+ },
243
353
  {
244
354
  "inputs": [
245
355
  {
@@ -464,6 +574,38 @@
464
574
  "internalType": "uint256",
465
575
  "name": "workerPaid",
466
576
  "type": "uint256"
577
+ },
578
+ {
579
+ "components": [
580
+ {
581
+ "internalType": "uint64",
582
+ "name": "revision",
583
+ "type": "uint64"
584
+ },
585
+ {
586
+ "internalType": "uint64",
587
+ "name": "expiresAt",
588
+ "type": "uint64"
589
+ },
590
+ {
591
+ "internalType": "address",
592
+ "name": "proposer",
593
+ "type": "address"
594
+ },
595
+ {
596
+ "internalType": "uint256",
597
+ "name": "workerAmount",
598
+ "type": "uint256"
599
+ },
600
+ {
601
+ "internalType": "bytes32",
602
+ "name": "proposalHash",
603
+ "type": "bytes32"
604
+ }
605
+ ],
606
+ "internalType": "struct A423Escrow.Proposal",
607
+ "name": "proposal",
608
+ "type": "tuple"
467
609
  }
468
610
  ],
469
611
  "internalType": "struct A423Escrow.Job",
@@ -474,6 +616,39 @@
474
616
  "stateMutability": "view",
475
617
  "type": "function"
476
618
  },
619
+ {
620
+ "inputs": [
621
+ {
622
+ "internalType": "bytes32",
623
+ "name": "id",
624
+ "type": "bytes32"
625
+ },
626
+ {
627
+ "internalType": "uint64",
628
+ "name": "expectedRevision",
629
+ "type": "uint64"
630
+ },
631
+ {
632
+ "internalType": "uint256",
633
+ "name": "workerAmount",
634
+ "type": "uint256"
635
+ },
636
+ {
637
+ "internalType": "bytes32",
638
+ "name": "proposalHash",
639
+ "type": "bytes32"
640
+ },
641
+ {
642
+ "internalType": "uint64",
643
+ "name": "expiresAt",
644
+ "type": "uint64"
645
+ }
646
+ ],
647
+ "name": "proposeSettlement",
648
+ "outputs": [],
649
+ "stateMutability": "nonpayable",
650
+ "type": "function"
651
+ },
477
652
  {
478
653
  "inputs": [
479
654
  {
@@ -518,6 +693,122 @@
518
693
  "stateMutability": "nonpayable",
519
694
  "type": "function"
520
695
  },
696
+ {
697
+ "inputs": [
698
+ {
699
+ "components": [
700
+ {
701
+ "internalType": "bytes32",
702
+ "name": "jobId",
703
+ "type": "bytes32"
704
+ },
705
+ {
706
+ "internalType": "bytes32",
707
+ "name": "agreementHash",
708
+ "type": "bytes32"
709
+ },
710
+ {
711
+ "internalType": "uint64",
712
+ "name": "escrowVersion",
713
+ "type": "uint64"
714
+ },
715
+ {
716
+ "internalType": "uint256",
717
+ "name": "workerAmount",
718
+ "type": "uint256"
719
+ },
720
+ {
721
+ "internalType": "uint256",
722
+ "name": "payerAmount",
723
+ "type": "uint256"
724
+ },
725
+ {
726
+ "internalType": "bytes32",
727
+ "name": "proposalHash",
728
+ "type": "bytes32"
729
+ },
730
+ {
731
+ "internalType": "uint64",
732
+ "name": "expiresAt",
733
+ "type": "uint64"
734
+ }
735
+ ],
736
+ "internalType": "struct A423Escrow.ClosingSettlement",
737
+ "name": "s",
738
+ "type": "tuple"
739
+ },
740
+ {
741
+ "internalType": "bytes",
742
+ "name": "payerSignature",
743
+ "type": "bytes"
744
+ },
745
+ {
746
+ "internalType": "bytes",
747
+ "name": "workerSignature",
748
+ "type": "bytes"
749
+ }
750
+ ],
751
+ "name": "settleByConsent",
752
+ "outputs": [],
753
+ "stateMutability": "nonpayable",
754
+ "type": "function"
755
+ },
756
+ {
757
+ "inputs": [
758
+ {
759
+ "components": [
760
+ {
761
+ "internalType": "bytes32",
762
+ "name": "jobId",
763
+ "type": "bytes32"
764
+ },
765
+ {
766
+ "internalType": "bytes32",
767
+ "name": "agreementHash",
768
+ "type": "bytes32"
769
+ },
770
+ {
771
+ "internalType": "uint64",
772
+ "name": "escrowVersion",
773
+ "type": "uint64"
774
+ },
775
+ {
776
+ "internalType": "uint256",
777
+ "name": "workerAmount",
778
+ "type": "uint256"
779
+ },
780
+ {
781
+ "internalType": "uint256",
782
+ "name": "payerAmount",
783
+ "type": "uint256"
784
+ },
785
+ {
786
+ "internalType": "bytes32",
787
+ "name": "proposalHash",
788
+ "type": "bytes32"
789
+ },
790
+ {
791
+ "internalType": "uint64",
792
+ "name": "expiresAt",
793
+ "type": "uint64"
794
+ }
795
+ ],
796
+ "internalType": "struct A423Escrow.ClosingSettlement",
797
+ "name": "s",
798
+ "type": "tuple"
799
+ }
800
+ ],
801
+ "name": "settlementDigest",
802
+ "outputs": [
803
+ {
804
+ "internalType": "bytes32",
805
+ "name": "",
806
+ "type": "bytes32"
807
+ }
808
+ ],
809
+ "stateMutability": "view",
810
+ "type": "function"
811
+ },
521
812
  {
522
813
  "inputs": [
523
814
  {
@@ -657,5 +948,5 @@
657
948
  "type": "function"
658
949
  }
659
950
  ],
660
- "bytecode": "0x610180604052348015610010575f5ffd5b5060405161269d38038061269d83398101604081905261002f916101df565b6040518060400160405280600a81526020016941343233457363726f7760b01b815250604051806040016040528060018152602001603160f81b81525060015f8190555061008760018361016760201b90919060201c565b61012052610096816002610167565b61014052815160208084019190912060e052815190820120610100524660a05261012260e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b60805250503060c0526001600160a01b0381163b5f0361015557604051630256965f60e01b815260040160405180910390fd5b6001600160a01b0316610160526103cc565b5f6020835110156101825761017b83610199565b9050610193565b8161018d84826102a4565b5060ff90505b92915050565b5f5f829050601f815111156101cc578260405163305a27a960e01b81526004016101c3919061035e565b60405180910390fd5b80516101d7826103a9565b179392505050565b5f602082840312156101ef575f5ffd5b81516001600160a01b0381168114610205575f5ffd5b9392505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061023457607f821691505b60208210810361025257634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561029f57805f5260205f20601f840160051c8101602085101561027d5750805b601f840160051c820191505b8181101561029c575f8155600101610289565b50505b505050565b81516001600160401b038111156102bd576102bd61020c565b6102d1816102cb8454610220565b84610258565b6020601f821160018114610303575f83156102ec5750848201515b5f19600385901b1c1916600184901b17845561029c565b5f84815260208120601f198516915b828110156103325787850151825560209485019460019092019101610312565b508482101561034f57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b602081525f82518060208401525f5b8181101561038a576020818601810151604086840101520161036d565b505f604082850101526040601f19601f83011684010191505092915050565b80516020808301519190811015610252575f1960209190910360031b1b16919050565b60805160a05160c05160e0516101005161012051610140516101605161223e61045f5f395f81816101f601528181610c3001528181610cc001528181610d0f015281816115760152818161160b01528181611683015281816116c9015261176b01525f61137b01525f61134901525f61150f01525f6114e701525f61144201525f61146c01525f611496015261223e5ff3fe608060405234801561000f575f5ffd5b50600436106100cb575f3560e01c806384b0196e11610088578063d26ff86e11610063578063d26ff86e146101ab578063edb70d9e146101be578063f729cf0d146101d1578063fc0c546a146101f1575f5ffd5b806384b0196e1461016a5780638a92631714610185578063cc3e049b14610198575f5ffd5b8063099d2518146100cf5780633aa36987146100f55780634e8fee001461011c57806367d42a8b14610131578063795ea18e1461014457806382cbf88b14610157575b5f5ffd5b6100e26100dd366004611b84565b610230565b6040519081526020015b60405180910390f35b6100e27f3a82e9543b510404d05948b3e6cbf4e32f66690f864ccb5ef67ee5927a49a4ba81565b61012f61012a366004611ba6565b610288565b005b61012f61013f366004611bc6565b61039f565b61012f610152366004611bc6565b61046f565b61012f610165366004611ba6565b6105cb565b61017261070e565b6040516100ec9796959493929190611c20565b61012f610193366004611cb6565b610750565b61012f6101a6366004611bc6565b610e23565b61012f6101b9366004611ba6565b610eab565b61012f6101cc366004611ba6565b610fb1565b6101e46101df366004611bc6565b611089565b6040516100ec9190611d69565b6102187f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100ec565b5f6102827f3a82e9543b510404d05948b3e6cbf4e32f66690f864ccb5ef67ee5927a49a4ba83604051602001610267929190611ed6565b6040516020818303038152906040528051906020012061120b565b92915050565b5f828152600360208190526040909120908101546001600160a01b031633146102c3576040516282b42960e81b815260040160405180910390fd5b6002600882015460ff1660078111156102de576102de611d35565b146102fc57604051636f20b45d60e11b815260040160405180910390fd5b6006810154600160401b90046001600160401b03164211156103315760405163637910d560e11b815260040160405180910390fd5b8060090154821461035557604051630256965f60e01b815260040160405180910390fd5b60088101805460ff1916600317905560405182815283907f5c83c73bb0b96f8bc4b95aabcb7980de29ee8ec40cf1aa83c5bd999b44077557906020015b60405180910390a2505050565b6103a7611237565b5f818152600360208190526040909120908101546001600160a01b031633146103e2576040516282b42960e81b815260040160405180910390fd5b6003600882015460ff1660078111156103fd576103fd611d35565b1461041b57604051636f20b45d60e11b815260040160405180910390fd5b6006810154600160801b90046001600160401b03164211156104505760405163637910d560e11b815260040160405180910390fd5b6104628282835f01600501545f61125f565b5061046c60015f55565b50565b610477611237565b5f8181526003602052604090206002600882015460ff16600781111561049f5761049f611d35565b141580156104c657506003600882015460ff1660078111156104c3576104c3611d35565b14155b80156104eb57506004600882015460ff1660078111156104e8576104e8611d35565b14155b1561050957604051636f20b45d60e11b815260040160405180910390fd5b6006810154600160801b90046001600160401b0316421161053d5760405163637910d560e11b815260040160405180910390fd5b600681015460058201545f9161271091600160c01b90910461ffff1690610565908390611fff565b61056f9190612026565b610579919061203d565b60068301546005840154600160c01b90910461ffff169061059d906127109061203d565b6105a79190612026565b6105b19190612050565b90506105c0838383600361125f565b505061046c60015f55565b5f82815260036020526040902060018101546001600160a01b03163314801590610602575060028101546001600160a01b03163314155b801561061b575060038101546001600160a01b03163314155b15610638576040516282b42960e81b815260040160405180910390fd5b6002600882015460ff16600781111561065357610653611d35565b1415801561067a57506003600882015460ff16600781111561067757610677611d35565b14155b1561069857604051636f20b45d60e11b815260040160405180910390fd5b6006810154600160801b90046001600160401b03164211156106cd5760405163637910d560e11b815260040160405180910390fd5b60088101805460ff1916600417905560405182815283907f8e39eab2c454d024fb5c89b50dabc51f5068c7a283891d06aa91f5ba96acded190602001610392565b5f6060805f5f5f606061071f611342565b610727611374565b604080515f80825260208201909252600f60f81b9b939a50919850469750309650945092509050565b610758611237565b6107686040840160208501612063565b6001600160a01b0316336001600160a01b031614610798576040516282b42960e81b815260040160405180910390fd5b82355f9081526003602052604081206008015460ff1660078111156107bf576107bf611d35565b146107dd57604051636f20b45d60e11b815260040160405180910390fd5b823515806107ee5750610140830135155b806107fb575060a0830135155b8061081d57505f6108126060850160408601612063565b6001600160a01b0316145b8061085757506108336040840160208501612063565b6001600160a01b031661084c6060850160408601612063565b6001600160a01b0316145b8061087957505f61086e6080850160608601612063565b6001600160a01b0316145b8061089b57505f61089060a0850160808601612063565b6001600160a01b0316145b806108d557506108b16040840160208501612063565b6001600160a01b03166108ca60a0850160808601612063565b6001600160a01b0316145b8061090f57506108eb6060840160408501612063565b6001600160a01b031661090460a0850160808601612063565b6001600160a01b0316145b80610930575061271061092a6101408501610120860161207c565b61ffff16115b1561094e57604051630256965f60e01b815260040160405180910390fd5b4261095f60e0850160c08601612095565b6001600160401b03161115806109a6575061098060e0840160c08501612095565b6001600160401b031661099a610100850160e08601612095565b6001600160401b031611155b806109e457506109bd610100840160e08501612095565b6001600160401b03166109d861012085016101008601612095565b6001600160401b031611155b15610a0257604051630256965f60e01b815260040160405180910390fd5b610a126060840160408501612063565b6001600160a01b0316610a62610a2785610230565b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506113a192505050565b6001600160a01b031614610a88576040516282b42960e81b815260040160405180910390fd5b604051806080016040528084803603810190610aa491906120e3565b8152602001600181525f602080830182905260409283018290528635825260038082529183902084518051825580830151600180840180546001600160a01b039384166001600160a01b03199182161790915596830151600285018054918416918916919091179055606083015195840180549683169688169690961790955560808201516004840180549190921696169590951790945560a0840151600582015560c084015160068201805460e087015161010088015161012089015161ffff16600160c01b0261ffff60c01b196001600160401b03928316600160801b021669ffffffffffffffffffff60801b19938316600160401b026fffffffffffffffffffffffffffffffff19909516929096169190911792909217169290921791909117905561014090930151600780850191909155908401516008840180549193909260ff19909216918490811115610bff57610bff611d35565b02179055506040828101516009830155606090920151600a90910155516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610c7d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ca191906121ac565b9050610cec610cb66040860160208701612063565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016903060a08801356113c9565b610cfa60a085013582612050565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610d5c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d8091906121ac565b14610d9e5760405163570883e560e01b815260040160405180910390fd5b610dae6040850160208601612063565b6001600160a01b031661014085013585357f32f3ba658fc1eefa6d5ca6ba35e8715bb439f7713edf2d61c03f4920fcb8cbab610df06060890160408a01612063565b604080516001600160a01b03909216825260a08a013560208301520160405180910390a450610e1e60015f55565b505050565b610e2b611237565b5f8181526003602052604090206001600882015460ff166007811115610e5357610e53611d35565b14610e7157604051636f20b45d60e11b815260040160405180910390fd5b60068101546001600160401b03164211610e9e5760405163637910d560e11b815260040160405180910390fd5b61046282825f600161125f565b5f82815260036020526040902060028101546001600160a01b03163314610ee4576040516282b42960e81b815260040160405180910390fd5b6001600882015460ff166007811115610eff57610eff611d35565b14610f1d57604051636f20b45d60e11b815260040160405180910390fd5b60068101546001600160401b0316421115610f4b5760405163637910d560e11b815260040160405180910390fd5b81610f6957604051630256965f60e01b815260040160405180910390fd5b6009810182905560088101805460ff1916600217905560405182815283907fa2f32e666157494cac7b795a43a2914dcb77efd9515b47db67dd15d332234f9790602001610392565b610fb9611237565b5f82815260036020526040902060048101546001600160a01b03163314610ff2576040516282b42960e81b815260040160405180910390fd5b6004600882015460ff16600781111561100d5761100d611d35565b1461102b57604051636f20b45d60e11b815260040160405180910390fd5b6006810154600160801b90046001600160401b03164211806110505750600581015482115b1561106e57604051630256965f60e01b815260040160405180910390fd5b61107b838284600261125f565b5061108560015f55565b5050565b604080516101e0810182525f6080820181815260a0830182905260c0830182905260e08301829052610100830182905261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c0830182905282526020820181905291810182905260608101919091525f8281526003602081815260409283902083516101e0810190945280546080850190815260018201546001600160a01b0390811660a08701526002830154811660c087015293820154841660e08601526004820154909316610100850152600581015461012085015260068101546001600160401b03808216610140870152600160401b82048116610160870152600160801b820416610180860152600160c01b900461ffff166101a08501526007808201546101c0860152928452600881015490929184019160ff909116908111156111dc576111dc611d35565b60078111156111ed576111ed611d35565b815260098201546020820152600a9091015460409091015292915050565b5f610282611217611436565b8360405161190160f01b8152600281019290925260228201526042902090565b60025f540361125957604051633ee5aeb560e01b815260040160405180910390fd5b60025f55565b60058301545f906112719084906121c3565b9050821561128d578015611286576007611290565b6005611290565b60065b60088501805460ff191660018360078111156112ae576112ae611d35565b0217905550600a840183905582156112d85760028401546112d8906001600160a01b03168461155f565b80156112f65760018401546112f6906001600160a01b03168261155f565b604080518481526020810183905260ff841681830152905186917fb3a77f60f2042a66aa50b5810774aab5f1a2dd6799ee891ebb9fe98b95fec57f919081900360600190a25050505050565b606061136f7f000000000000000000000000000000000000000000000000000000000000000060016117f5565b905090565b606061136f7f000000000000000000000000000000000000000000000000000000000000000060026117f5565b5f5f5f5f6113af868661189e565b9250925092506113bf82826118e7565b5090949350505050565b6040516001600160a01b0384811660248301528381166044830152606482018390526114309186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506119a4565b50505050565b5f306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561148e57507f000000000000000000000000000000000000000000000000000000000000000046145b156114b857507f000000000000000000000000000000000000000000000000000000000000000090565b61136f604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156115c3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115e791906121ac565b6040516370a0823160e01b81526001600160a01b0385811660048301529192505f917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015611650573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061167491906121ac565b90506116aa6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168585611a10565b6116b483836121c3565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611716573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061173a91906121ac565b1415806117d7575061174c8382612050565b6040516370a0823160e01b81526001600160a01b0386811660048301527f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156117b0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117d491906121ac565b14155b156114305760405163570883e560e01b815260040160405180910390fd5b606060ff831461180f5761180883611a41565b9050610282565b81805461181b906121d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611847906121d6565b80156118925780601f1061186957610100808354040283529160200191611892565b820191905f5260205f20905b81548152906001019060200180831161187557829003601f168201915b50505050509050610282565b5f5f5f83516041036118d5576020840151604085015160608601515f1a6118c788828585611a7e565b9550955095505050506118e0565b505081515f91506002905b9250925092565b5f8260038111156118fa576118fa611d35565b03611903575050565b600182600381111561191757611917611d35565b036119355760405163f645eedf60e01b815260040160405180910390fd5b600282600381111561194957611949611d35565b0361196f5760405163fce698f760e01b8152600481018290526024015b60405180910390fd5b600382600381111561198357611983611d35565b03611085576040516335e2f38360e21b815260048101829052602401611966565b5f5f60205f8451602086015f885af1806119c3576040513d5f823e3d81fd5b50505f513d915081156119da5780600114156119e7565b6001600160a01b0384163b155b1561143057604051635274afe760e01b81526001600160a01b0385166004820152602401611966565b6040516001600160a01b03838116602483015260448201839052610e1e91859182169063a9059cbb906064016113fe565b60605f611a4d83611b46565b6040805160208082528183019092529192505f91906020820181803683375050509182525060208101929092525090565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115611ab757505f91506003905082611b3c565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015611b08573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b038116611b3357505f925060019150829050611b3c565b92505f91508190505b9450945094915050565b5f60ff8216601f81111561028257604051632cd44ac360e21b815260040160405180910390fd5b5f6101608284031215611b7e575f5ffd5b50919050565b5f6101608284031215611b95575f5ffd5b611b9f8383611b6d565b9392505050565b5f5f60408385031215611bb7575f5ffd5b50508035926020909101359150565b5f60208284031215611bd6575f5ffd5b5035919050565b5f81518084525f5b81811015611c0157602081850181015186830182015201611be5565b505f602082860101526020601f19601f83011685010191505092915050565b60ff60f81b8816815260e060208201525f611c3e60e0830189611bdd565b8281036040840152611c508189611bdd565b606084018890526001600160a01b038716608085015260a0840186905283810360c0850152845180825260208087019350909101905f5b81811015611ca5578351835260209384019390920191600101611c87565b50909b9a5050505050505050505050565b5f5f5f6101808486031215611cc9575f5ffd5b611cd38585611b6d565b92506101608401356001600160401b03811115611cee575f5ffd5b8401601f81018613611cfe575f5ffd5b80356001600160401b03811115611d13575f5ffd5b866020828401011115611d24575f5ffd5b939660209190910195509293505050565b634e487b7160e01b5f52602160045260245ffd5b60088110611d6557634e487b7160e01b5f52602160045260245ffd5b9052565b5f6101c0820190508251805183526020810151611d9160208501826001600160a01b03169052565b506040810151611dac60408501826001600160a01b03169052565b506060810151611dc760608501826001600160a01b03169052565b506080810151611de260808501826001600160a01b03169052565b5060a081015160a084015260c0810151611e0760c08501826001600160401b03169052565b5060e0810151611e2260e08501826001600160401b03169052565b50610100810151611e3f6101008501826001600160401b03169052565b50610120810151611e5761012085018261ffff169052565b50610140810151610140840152506020830151611e78610160840182611d49565b5060408301516101808301526060909201516101a09091015290565b80356001600160a01b0381168114611eaa575f5ffd5b919050565b80356001600160401b0381168114611eaa575f5ffd5b803561ffff81168114611eaa575f5ffd5b8281528135602080830191909152610180820190611ef5908401611e94565b6001600160a01b038116604084015250611f1160408401611e94565b6001600160a01b038116606084015250611f2d60608401611e94565b6001600160a01b038116608084015250611f4960808401611e94565b6001600160a01b03811660a08401525060a083013560c083810191909152611f72908401611eaf565b6001600160401b03811660e084015250611f8e60e08401611eaf565b6001600160401b03811661010084015250611fac6101008401611eaf565b6001600160401b03811661012084015250611fca6101208401611ec5565b61ffff81166101408401525061014092909201356101609190910152919050565b634e487b7160e01b5f52601260045260245ffd5b5f8261200d5761200d611feb565b500690565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761028257610282612012565b5f8261204b5761204b611feb565b500490565b8082018082111561028257610282612012565b5f60208284031215612073575f5ffd5b611b9f82611e94565b5f6020828403121561208c575f5ffd5b611b9f82611ec5565b5f602082840312156120a5575f5ffd5b611b9f82611eaf565b60405161016081016001600160401b03811182821017156120dd57634e487b7160e01b5f52604160045260245ffd5b60405290565b5f6101608284031280156120f5575f5ffd5b506120fe6120ae565b8235815261210e60208401611e94565b602082015261211f60408401611e94565b604082015261213060608401611e94565b606082015261214160808401611e94565b608082015260a0838101359082015261215c60c08401611eaf565b60c082015261216d60e08401611eaf565b60e082015261217f6101008401611eaf565b6101008201526121926101208401611ec5565b610120820152610140928301359281019290925250919050565b5f602082840312156121bc575f5ffd5b5051919050565b8181038181111561028257610282612012565b600181811c908216806121ea57607f821691505b602082108103611b7e57634e487b7160e01b5f52602260045260245ffdfea26469706673582212209a4cf890584b4e1fcda7ef5edc35397cda09ec7966b5a78649bc7c637ecb7d2264736f6c634300081e0033"
951
+ "bytecode": "0x610180604052348015610010575f5ffd5b5060405161348438038061348483398101604081905261002f916101df565b6040518060400160405280600a81526020016941343233457363726f7760b01b815250604051806040016040528060018152602001603160f81b81525060015f8190555061008760018361016760201b90919060201c565b61012052610096816002610167565b61014052815160208084019190912060e052815190820120610100524660a05261012260e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b60805250503060c0526001600160a01b0381163b5f0361015557604051630256965f60e01b815260040160405180910390fd5b6001600160a01b0316610160526103cc565b5f6020835110156101825761017b83610199565b9050610193565b8161018d84826102a4565b5060ff90505b92915050565b5f5f829050601f815111156101cc578260405163305a27a960e01b81526004016101c3919061035e565b60405180910390fd5b80516101d7826103a9565b179392505050565b5f602082840312156101ef575f5ffd5b81516001600160a01b0381168114610205575f5ffd5b9392505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061023457607f821691505b60208210810361025257634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561029f57805f5260205f20601f840160051c8101602085101561027d5750805b601f840160051c820191505b8181101561029c575f8155600101610289565b50505b505050565b81516001600160401b038111156102bd576102bd61020c565b6102d1816102cb8454610220565b84610258565b6020601f821160018114610303575f83156102ec5750848201515b5f19600385901b1c1916600184901b17845561029c565b5f84815260208120601f198516915b828110156103325787850151825560209485019460019092019101610312565b508482101561034f57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b602081525f82518060208401525f5b8181101561038a576020818601810151604086840101520161036d565b505f604082850101526040601f19601f83011684010191505092915050565b80516020808301519190811015610252575f1960209190910360031b1b16919050565b60805160a05160c05160e0516101005161012051610140516101605161302561045f5f395f81816102af015281816114bf015281816115470152818161159601528181611ee101528181611f7601528181611fee0152818161203401526120d601525f611e0f01525f611ddd01525f61223901525f61221101525f61216c01525f61219601525f6121c001526130255ff3fe608060405234801561000f575f5ffd5b5060043610610111575f3560e01c806382cbf88b1161009e578063cc3e049b1161006e578063cc3e049b14610251578063d26ff86e14610264578063edb70d9e14610277578063f729cf0d1461028a578063fc0c546a146102aa575f5ffd5b806382cbf88b146101e957806384b0196e146101fc5780638a92631714610217578063b1fb79c01461022a575f5ffd5b80633cf973a8116100e45780633cf973a81461018a5780634e8fee001461019d57806367d42a8b146101b05780636d78dc2e146101c3578063795ea18e146101d6575f5ffd5b806308834fb714610115578063099d25181461012a57806316db9070146101505780633aa3698714610163575b5f5ffd5b6101286101233660046126e5565b6102e9565b005b61013d61013836600461272f565b6103ce565b6040519081526020015b60405180910390f35b61012861015e366004612751565b610426565b61013d7f3a82e9543b510404d05948b3e6cbf4e32f66690f864ccb5ef67ee5927a49a4ba81565b6101286101983660046127f1565b61075c565b6101286101ab366004612872565b61090e565b6101286101be366004612892565b610a25565b61013d6101d13660046128a9565b610af5565b6101286101e4366004612892565b610b2c565b6101286101f7366004612872565b610cb8565b610204610e43565b6040516101479796959493929190612906565b61012861022536600461299c565b610e85565b61013d7f540b958eec7b6eee84ef0a13bf83a448a990f8e9566a0f28bb771a27d0c364d581565b61012861025f366004612892565b6116a6565b610128610272366004612872565b611784565b610128610285366004612872565b61188a565b61029d610298366004612892565b611962565b6040516101479190612a21565b6102d17f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610147565b6102f1611ad0565b5f83815260036020526040902060018101546001600160a01b03163314801590610328575060028101546001600160a01b03163314155b8061033f5750600c8101546001600160a01b031633145b1561035c576040516282b42960e81b815260040160405180910390fd5b610367818484611af8565b604080516001600160401b03851681526020810184905285917fb2bf4a774270088cf58089bef9455cc4ec4e914fda289fb7fff5025eafc533c8910160405180910390a26103bf848283600b01600201546004611bc3565b506103c960015f55565b505050565b5f6104207f3a82e9543b510404d05948b3e6cbf4e32f66690f864ccb5ef67ee5927a49a4ba83604051602001610405929190612bbf565b60405160208183030381529060405280519060200120611cac565b92915050565b5f85815260036020526040902060018101546001600160a01b0316331480159061045d575060028101546001600160a01b03163314155b1561047a576040516282b42960e81b815260040160405180910390fd5b600160088083015460ff1690811115610495576104956129ed565b141580156104bc5750600260088083015460ff16908111156104b9576104b96129ed565b14155b80156104e15750600360088083015460ff16908111156104de576104de6129ed565b14155b8015610504575060088181015460ff1681811115610501576105016129ed565b14155b1561052257604051636f20b45d60e11b815260040160405180910390fd5b600b8101546001600160401b0386811691161415806105445750600581015484115b8061054d575082155b1561056b57604051630256965f60e01b815260040160405180910390fd5b60088181015460ff1681811115610584576105846129ed565b14801561059d5750600c8101546001600160a01b031633145b156105ba576040516282b42960e81b815260040160405180910390fd5b42826001600160401b03161115806105e9575060068101546001600160401b03600160801b9091048116908316115b8061060757506006810154600160801b90046001600160401b031642115b156106255760405163637910d560e11b815260040160405180910390fd5b6040518060a0016040528086600161063d9190612ce8565b6001600160401b03908116825284811660208084019190915233604080850182905260608086018b905260809586018a90528651600b89018054958901519187166001600160801b031990961695909517600160401b91871691909102179384905590860151600c880180546001600160a01b0319166001600160a01b03909216919091179055850151600d8701559390920151600e8501556008808501805460ff19169091179055600584015489927f313fe6db037665faaf39fbf4329c07f3e7cd3329ac8ae51afa842bcc974e42c3921690889061071e908290612d07565b604080516001600160401b039485168152602081019390935282015260608101889052908616608082015260a00160405180910390a3505050505050565b610764611ad0565b84355f90815260036020526040908190209061079690829061078c9060608a01908a01612d1a565b8860a00135611af8565b600781015460208701351415806107b55750600d810154606087013514155b806107d7575060058101546107cf90606088013590612d07565b866080013514155b8061080e5750600b810154600160401b90046001600160401b031661080260e0880160c08901612d1a565b6001600160401b031614155b1561082c57604051630256965f60e01b815260040160405180910390fd5b5f61083687610af5565b6001830154909150610853906001600160a01b0316828888611cd8565b158061087657506002820154610874906001600160a01b0316828686611cd8565b155b15610893576040516282b42960e81b815260040160405180910390fd5b86357fb2bf4a774270088cf58089bef9455cc4ec4e914fda289fb7fff5025eafc533c86108c660608a0160408b01612d1a565b604080516001600160401b03909216825260a08b013560208301520160405180910390a26108fc87358360608a01356004611bc3565b505061090760015f55565b5050505050565b5f828152600360208190526040909120908101546001600160a01b03163314610949576040516282b42960e81b815260040160405180910390fd5b600260088083015460ff1690811115610964576109646129ed565b1461098257604051636f20b45d60e11b815260040160405180910390fd5b6006810154600160401b90046001600160401b03164211156109b75760405163637910d560e11b815260040160405180910390fd5b806009015482146109db57604051630256965f60e01b815260040160405180910390fd5b60088101805460ff1916600317905560405182815283907f5c83c73bb0b96f8bc4b95aabcb7980de29ee8ec40cf1aa83c5bd999b44077557906020015b60405180910390a2505050565b610a2d611ad0565b5f818152600360208190526040909120908101546001600160a01b03163314610a68576040516282b42960e81b815260040160405180910390fd5b600360088083015460ff1690811115610a8357610a836129ed565b14610aa157604051636f20b45d60e11b815260040160405180910390fd5b6006810154600160801b90046001600160401b0316421115610ad65760405163637910d560e11b815260040160405180910390fd5b610ae88282835f01600501545f611bc3565b50610af260015f55565b50565b5f6104207f540b958eec7b6eee84ef0a13bf83a448a990f8e9566a0f28bb771a27d0c364d583604051602001610405929190612d33565b610b34611ad0565b5f818152600360205260409020600260088083015460ff1690811115610b5c57610b5c6129ed565b14158015610b835750600360088083015460ff1690811115610b8057610b806129ed565b14155b8015610ba85750600460088083015460ff1690811115610ba557610ba56129ed565b14155b8015610bcb575060088181015460ff1681811115610bc857610bc86129ed565b14155b80610bd857506009810154155b15610bf657604051636f20b45d60e11b815260040160405180910390fd5b6006810154600160801b90046001600160401b03164211610c2a5760405163637910d560e11b815260040160405180910390fd5b600681015460058201545f9161271091600160c01b90910461ffff1690610c52908390612dca565b610c5c9190612ddd565b610c669190612df4565b60068301546005840154600160c01b90910461ffff1690610c8a9061271090612df4565b610c949190612ddd565b610c9e9190612e07565b9050610cad8383836003611bc3565b5050610af260015f55565b5f82815260036020526040902060018101546001600160a01b03163314801590610cef575060028101546001600160a01b03163314155b8015610d08575060038101546001600160a01b03163314155b15610d25576040516282b42960e81b815260040160405180910390fd5b600260088083015460ff1690811115610d4057610d406129ed565b14158015610d675750600360088083015460ff1690811115610d6457610d646129ed565b14155b8015610d8a575060088181015460ff1681811115610d8757610d876129ed565b14155b8015610daf5750600160088083015460ff1690811115610dac57610dac6129ed565b14155b15610dcd57604051636f20b45d60e11b815260040160405180910390fd5b6006810154600160801b90046001600160401b0316421115610e025760405163637910d560e11b815260040160405180910390fd5b60088101805460ff1916600417905560405182815283907f8e39eab2c454d024fb5c89b50dabc51f5068c7a283891d06aa91f5ba96acded190602001610a18565b5f6060805f5f5f6060610e54611dd6565b610e5c611e08565b604080515f80825260208201909252600f60f81b9b939a50919850469750309650945092509050565b610e8d611ad0565b610e9d6040840160208501612e1a565b6001600160a01b0316336001600160a01b031614610ecd576040516282b42960e81b815260040160405180910390fd5b82355f90815260036020526040812060089081015460ff1690811115610ef557610ef56129ed565b14610f1357604051636f20b45d60e11b815260040160405180910390fd5b82351580610f245750610140830135155b80610f31575060a0830135155b80610f5357505f610f486060850160408601612e1a565b6001600160a01b0316145b80610f8d5750610f696040840160208501612e1a565b6001600160a01b0316610f826060850160408601612e1a565b6001600160a01b0316145b80610faf57505f610fa46080850160608601612e1a565b6001600160a01b0316145b80610fd157505f610fc660a0850160808601612e1a565b6001600160a01b0316145b8061100b5750610fe76040840160208501612e1a565b6001600160a01b031661100060a0850160808601612e1a565b6001600160a01b0316145b8061104557506110216060840160408501612e1a565b6001600160a01b031661103a60a0850160808601612e1a565b6001600160a01b0316145b80611066575061271061106061014085016101208601612e33565b61ffff16115b1561108457604051630256965f60e01b815260040160405180910390fd5b4261109560e0850160c08601612d1a565b6001600160401b03161115806110dc57506110b660e0840160c08501612d1a565b6001600160401b03166110d0610100850160e08601612d1a565b6001600160401b031611155b8061111a57506110f3610100840160e08501612d1a565b6001600160401b031661110e61012085016101008601612d1a565b6001600160401b031611155b1561113857604051630256965f60e01b815260040160405180910390fd5b5f6111496060850160408601612e1a565b6001600160a01b03163b5f036111ca576111696060850160408601612e1a565b6001600160a01b03166111b961117e866103ce565b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250611e3592505050565b6001600160a01b031614905061126b565b6111da6060850160408601612e1a565b6001600160a01b0316631626ba7e6111f1866103ce565b85856040518463ffffffff1660e01b815260040161121193929190612e4c565b602060405180830381865afa92505050801561124a575060408051601f3d908101601f1916820190925261124791810190612e81565b60015b61125557505f61126b565b6001600160e01b031916630b135d3f60e11b1490505b80611288576040516282b42960e81b815260040160405180910390fd5b6040518060a00160405280858036038101906112a49190612edd565b8152602001600181525f60208083018290526040808401839052805160a0808201835284825281840185905281830185905260608281018690526080808401879052968101929092528a35855260038085529483902087518051825580860151600180840180546001600160a01b039384166001600160a01b0319918216179091559683015160028501805491841691891691909117905594820151978301805498821698871698909817909755968701516004820180549190971694169390931790945592840151600582015560c084015160068201805460e087015161010088015161012089015161ffff16600160c01b0261ffff60c01b196001600160401b03928316600160801b021669ffffffffffffffffffff60801b19938316600160401b026001600160801b03199095169690921695909517929092171617919091179055610140909301516007840155830151600880840180549293909260ff1916918490811115611419576114196129ed565b02179055506040828101516009830155606080840151600a8401556080938401518051600b8501805460208401516001600160401b03908116600160401b026001600160801b031990921693169290921791909117905580830151600c850180546001600160a01b039283166001600160a01b031990911617905591810151600d85015590930151600e90920191909155516370a0823160e01b81523060048201525f917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015611504573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115289190612fa6565b905061157361153d6040870160208801612e1a565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016903060a0890135611e5d565b61158160a086013582612e07565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156115e3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116079190612fa6565b146116255760405163570883e560e01b815260040160405180910390fd5b6116356040860160208701612e1a565b6001600160a01b031661014086013586357f32f3ba658fc1eefa6d5ca6ba35e8715bb439f7713edf2d61c03f4920fcb8cbab61167760608a0160408b01612e1a565b604080516001600160a01b03909216825260a08b013560208301520160405180910390a450506103c960015f55565b6116ae611ad0565b5f818152600360205260409020600160088083015460ff16908111156116d6576116d66129ed565b1415801561172c575060088181015460ff16818111156116f8576116f86129ed565b148061171c5750600460088083015460ff169081111561171a5761171a6129ed565b145b801561172a57506009810154155b155b1561174a57604051636f20b45d60e11b815260040160405180910390fd5b60068101546001600160401b031642116117775760405163637910d560e11b815260040160405180910390fd5b610ae882825f6001611bc3565b5f82815260036020526040902060028101546001600160a01b031633146117bd576040516282b42960e81b815260040160405180910390fd5b600160088083015460ff16908111156117d8576117d86129ed565b146117f657604051636f20b45d60e11b815260040160405180910390fd5b60068101546001600160401b03164211156118245760405163637910d560e11b815260040160405180910390fd5b8161184257604051630256965f60e01b815260040160405180910390fd5b6009810182905560088101805460ff1916600217905560405182815283907fa2f32e666157494cac7b795a43a2914dcb77efd9515b47db67dd15d332234f9790602001610a18565b611892611ad0565b5f82815260036020526040902060048101546001600160a01b031633146118cb576040516282b42960e81b815260040160405180910390fd5b600460088083015460ff16908111156118e6576118e66129ed565b1461190457604051636f20b45d60e11b815260040160405180910390fd5b6006810154600160801b90046001600160401b03164211806119295750600581015482115b1561194757604051630256965f60e01b815260040160405180910390fd5b6119548382846002611bc3565b5061195e60015f55565b5050565b61196a612601565b5f8281526003602081815260409283902083516102008101909452805460a0850190815260018201546001600160a01b0390811660c08701526002830154811660e08701529382015484166101008601526004820154909316610120850152600581015461014085015260068101546001600160401b03808216610160870152600160401b82048116610180870152600160801b8204166101a0860152600160c01b900461ffff166101c085015260078101546101e08501529183526008808301549184019160ff1690811115611a4357611a436129ed565b6008811115611a5457611a546129ed565b81526009820154602080830191909152600a830154604080840191909152805160a081018252600b8501546001600160401b038082168352600160401b9091041692810192909252600c8401546001600160a01b031690820152600d830154606082810191909152600e90930154608082015291015292915050565b60025f5403611af257604051633ee5aeb560e01b815260040160405180910390fd5b60025f55565b60088381015460ff1681811115611b1157611b116129ed565b14611b2f57604051636f20b45d60e11b815260040160405180910390fd5b600b8301546001600160401b038381169116141580611b525750600e8301548114155b15611b7057604051630256965f60e01b815260040160405180910390fd5b600b830154600160401b90046001600160401b0316421180611ba557506006830154600160801b90046001600160401b031642115b156103c95760405163637910d560e11b815260040160405180910390fd5b60058301545f90611bd5908490612d07565b90508215611bf1578015611bea576007611bf4565b6005611bf4565b60065b846008015f6101000a81548160ff02191690836008811115611c1857611c186129ed565b0217905550600a84018390558215611c42576002840154611c42906001600160a01b031684611eca565b8015611c60576001840154611c60906001600160a01b031682611eca565b604080518481526020810183905260ff841681830152905186917fb3a77f60f2042a66aa50b5810774aab5f1a2dd6799ee891ebb9fe98b95fec57f919081900360600190a25050505050565b5f610420611cb8612160565b8360405161190160f01b8152600281019290925260228201526042902090565b5f846001600160a01b03163b5f03611d4457846001600160a01b0316611d338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250611e3592505050565b6001600160a01b0316149050611dce565b604051630b135d3f60e11b81526001600160a01b03861690631626ba7e90611d7490879087908790600401612e4c565b602060405180830381865afa925050508015611dad575060408051601f3d908101601f19168201909252611daa91810190612e81565b60015b611db857505f611dce565b6001600160e01b031916630b135d3f60e11b1490505b949350505050565b6060611e037f00000000000000000000000000000000000000000000000000000000000000006001612289565b905090565b6060611e037f00000000000000000000000000000000000000000000000000000000000000006002612289565b5f5f5f5f611e438686612332565b925092509250611e53828261237b565b5090949350505050565b6040516001600160a01b038481166024830152838116604483015260648201839052611ec49186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050612438565b50505050565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611f2e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f529190612fa6565b6040516370a0823160e01b81526001600160a01b0385811660048301529192505f917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015611fbb573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fdf9190612fa6565b90506120156001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001685856124a4565b61201f8383612d07565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612081573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120a59190612fa6565b14158061214257506120b78382612e07565b6040516370a0823160e01b81526001600160a01b0386811660048301527f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa15801561211b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061213f9190612fa6565b14155b15611ec45760405163570883e560e01b815260040160405180910390fd5b5f306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480156121b857507f000000000000000000000000000000000000000000000000000000000000000046145b156121e257507f000000000000000000000000000000000000000000000000000000000000000090565b611e03604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b606060ff83146122a35761229c836124d5565b9050610420565b8180546122af90612fbd565b80601f01602080910402602001604051908101604052809291908181526020018280546122db90612fbd565b80156123265780601f106122fd57610100808354040283529160200191612326565b820191905f5260205f20905b81548152906001019060200180831161230957829003601f168201915b50505050509050610420565b5f5f5f8351604103612369576020840151604085015160608601515f1a61235b88828585612512565b955095509550505050612374565b505081515f91506002905b9250925092565b5f82600381111561238e5761238e6129ed565b03612397575050565b60018260038111156123ab576123ab6129ed565b036123c95760405163f645eedf60e01b815260040160405180910390fd5b60028260038111156123dd576123dd6129ed565b036124035760405163fce698f760e01b8152600481018290526024015b60405180910390fd5b6003826003811115612417576124176129ed565b0361195e576040516335e2f38360e21b8152600481018290526024016123fa565b5f5f60205f8451602086015f885af180612457576040513d5f823e3d81fd5b50505f513d9150811561246e57806001141561247b565b6001600160a01b0384163b155b15611ec457604051635274afe760e01b81526001600160a01b03851660048201526024016123fa565b6040516001600160a01b038381166024830152604482018390526103c991859182169063a9059cbb90606401611e92565b60605f6124e1836125da565b6040805160208082528183019092529192505f91906020820181803683375050509182525060208101929092525090565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084111561254b57505f915060039050826125d0565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa15801561259c573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b0381166125c757505f9250600191508290506125d0565b92505f91508190505b9450945094915050565b5f60ff8216601f81111561042057604051632cd44ac360e21b815260040160405180910390fd5b6040805161020081019091525f60a0820181815260c0830182905260e08301829052610100830182905261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c083018290526101e0830191909152819081526020015f81526020015f81526020015f81526020016126c56040518060a001604052805f6001600160401b031681526020015f6001600160401b031681526020015f6001600160a01b031681526020015f81526020015f81525090565b905290565b80356001600160401b03811681146126e0575f5ffd5b919050565b5f5f5f606084860312156126f7575f5ffd5b83359250612707602085016126ca565b929592945050506040919091013590565b5f6101608284031215612729575f5ffd5b50919050565b5f6101608284031215612740575f5ffd5b61274a8383612718565b9392505050565b5f5f5f5f5f60a08688031215612765575f5ffd5b85359450612775602087016126ca565b93506040860135925060608601359150612791608087016126ca565b90509295509295909350565b5f60e08284031215612729575f5ffd5b5f5f83601f8401126127bd575f5ffd5b5081356001600160401b038111156127d3575f5ffd5b6020830191508360208285010111156127ea575f5ffd5b9250929050565b5f5f5f5f5f6101208688031215612806575f5ffd5b612810878761279d565b945060e08601356001600160401b0381111561282a575f5ffd5b612836888289016127ad565b9095509350506101008601356001600160401b03811115612855575f5ffd5b612861888289016127ad565b969995985093965092949392505050565b5f5f60408385031215612883575f5ffd5b50508035926020909101359150565b5f602082840312156128a2575f5ffd5b5035919050565b5f60e082840312156128b9575f5ffd5b61274a838361279d565b5f81518084525f5b818110156128e7576020818501810151868301820152016128cb565b505f602082860101526020601f19601f83011685010191505092915050565b60ff60f81b8816815260e060208201525f61292460e08301896128c3565b828103604084015261293681896128c3565b606084018890526001600160a01b038716608085015260a0840186905283810360c0850152845180825260208087019350909101905f5b8181101561298b57835183526020938401939092019160010161296d565b50909b9a5050505050505050505050565b5f5f5f61018084860312156129af575f5ffd5b6129b98585612718565b92506101608401356001600160401b038111156129d4575f5ffd5b6129e0868287016127ad565b9497909650939450505050565b634e487b7160e01b5f52602160045260245ffd5b60098110612a1d57634e487b7160e01b5f52602160045260245ffd5b9052565b5f610260820190508251805183526020810151612a4960208501826001600160a01b03169052565b506040810151612a6460408501826001600160a01b03169052565b506060810151612a7f60608501826001600160a01b03169052565b506080810151612a9a60808501826001600160a01b03169052565b5060a081015160a084015260c0810151612abf60c08501826001600160401b03169052565b5060e0810151612ada60e08501826001600160401b03169052565b50610100810151612af76101008501826001600160401b03169052565b50610120810151612b0f61012085018261ffff169052565b50610140810151610140840152506020830151612b30610160840182612a01565b506040838101516101808401526060808501516101a085015260809485015180516001600160401b039081166101c08701526020820151166101e0860152918201516001600160a01b0316610200850152810151610220840152909201516102409091015290565b80356001600160a01b03811681146126e0575f5ffd5b803561ffff811681146126e0575f5ffd5b8281528135602080830191909152610180820190612bde908401612b98565b6001600160a01b038116604084015250612bfa60408401612b98565b6001600160a01b038116606084015250612c1660608401612b98565b6001600160a01b038116608084015250612c3260808401612b98565b6001600160a01b03811660a08401525060a083013560c083810191909152612c5b9084016126ca565b6001600160401b03811660e084015250612c7760e084016126ca565b6001600160401b03811661010084015250612c9561010084016126ca565b6001600160401b03811661012084015250612cb36101208401612bae565b61ffff81166101408401525061014092909201356101609190910152919050565b634e487b7160e01b5f52601160045260245ffd5b6001600160401b03818116838216019081111561042057610420612cd4565b8181038181111561042057610420612cd4565b5f60208284031215612d2a575f5ffd5b61274a826126ca565b82815281356020808301919091528201356040808301919091526101008201906001600160401b0390612d679085016126ca565b1660608381019190915283013560808084019190915283013560a08084019190915283013560c0808401919091526001600160401b0390612da99085016126ca565b1660e08301529392505050565b634e487b7160e01b5f52601260045260245ffd5b5f82612dd857612dd8612db6565b500690565b808202811582820484141761042057610420612cd4565b5f82612e0257612e02612db6565b500490565b8082018082111561042057610420612cd4565b5f60208284031215612e2a575f5ffd5b61274a82612b98565b5f60208284031215612e43575f5ffd5b61274a82612bae565b83815260406020820152816040820152818360608301375f818301606090810191909152601f909201601f1916010192915050565b5f60208284031215612e91575f5ffd5b81516001600160e01b03198116811461274a575f5ffd5b60405161016081016001600160401b0381118282101715612ed757634e487b7160e01b5f52604160045260245ffd5b60405290565b5f610160828403128015612eef575f5ffd5b50612ef8612ea8565b82358152612f0860208401612b98565b6020820152612f1960408401612b98565b6040820152612f2a60608401612b98565b6060820152612f3b60808401612b98565b608082015260a08381013590820152612f5660c084016126ca565b60c0820152612f6760e084016126ca565b60e0820152612f7961010084016126ca565b610100820152612f8c6101208401612bae565b610120820152610140928301359281019290925250919050565b5f60208284031215612fb6575f5ffd5b5051919050565b600181811c90821680612fd157607f821691505b60208210810361272957634e487b7160e01b5f52602260045260245ffdfea26469706673582212203991425a1354567aa5fd3ad898314bfc11d4837d4af9efe72c5a51c61f6c5ff464736f6c634300081e0033"
661
952
  }