0x68575b07…67c7·#25,914,163·view on Etherscan
r, or a .wei name":"Token id must be a number";
swap.disabled=true;return}
const climbing=kind.value==="floor";
if(kind.value==="dutch"){
swap.textContent="A bid is fixed or climbing, not decaying";swap.disabled=true;return}
if(oneId&&climbing){
swap.textContent="A climbing bid takes any id — clear the token id";
swap.disabled=true;return}
if(!oneId){
const q=outAmt.value.trim();
if(q&&!/^\d+$/.test(q)){
swap.textContent="How many? a whole number";swap.disabled=true;return}
if(q&&!BigInt(q)){swap.textContent="Bid for at least one";swap.disabled=true;return}
if(q&&BigInt(q)>(1n<<128n)-1n){
swap.textContent="Too many to bid for at once";swap.disabled=true;return}
}
let bidAmt=0n;
try{bidAmt=amt.value.trim()?parseUnits(amt.value.trim(),f.dec):0n}catch{}
if(!bidAmt){
swap.textContent=climbing?"Set the most you will pay":"Set what you will pay";
swap.disabled=true;return}
if(climbing){
let openAmt=0n;
try{openAmt=floorAmt.value.trim()?parseUnits(floorAmt.value.trim(),f.dec):0n}catch{}
if(!openAmt){swap.textContent="Set an opening bid";swap.disabled=true;return}
if(openAmt>bidAmt){swap.textContent="Opening bid exceeds the maximum";swap.disabled=true;return}
if(!+dly.value){swap.textContent="A climbing bid needs a window";swap.disabled=true;return}
}else if(!oneId&&!+dly.value){
swap.textContent="A collection bid needs a window";swap.disabled=true;return}
if(bidAmt>fromBalance){swap.textContent="Insufficient balance";swap.disabled=true;return}
swap.textContent=oneId?`Bid for ${nftLabel(t.sym,t.addr,nftId.value)}`
:climbing?`Climbing bid for any ${t.sym}`:`Bid for any ${t.sym}`;
swap.disabled=false;return}
if(f.std==="nft"){
if(kind.value!=="fixed"){
swap.textContent="An NFT sells at a fixed price";swap.disabled=true;return}
if(!/^\d+$/.test(nftIdIn(f.addr,nftId.value))){
swap.textContent=isWns(f.addr)?"Name the .wei name, or the token id, to sell":"Name the token id to sell";
swap.disabled=true;return}
let ask=0n;
try{ask=outAmt.value.trim()?parseUnits(outAmt.value.trim(),t.dec):0n}catch{}
if(!ask){swap.textContent="Set a price";swap.disabled=true;return}
swap.textContent=`List ${nftLabel(f.sym,f.addr,nftId.value)}`;swap.disabled=false;return}
const dutch=kind.value==="dutch",bid=kind.value==="floor";
let sell=0n,want=0n,floor=0n,badOrderAmount=false;
try{if(amt.value.trim())sell=parseUnits(amt.value.trim(),f.dec);
if(outAmt.value.trim())want=parseUnits(outAmt.value.trim(),t.dec);
if((dutch||bid)&&floorAmt.value.trim())floor=parseUnits(floorAmt.value.trim(),bid?f.dec:t.dec)}
catch{badOrderAmount=true}
if(badOrderAmount){swap.textContent="Invalid order amount";swap.disabled=true;return}
if(!sell||!want){swap.textContent=bid?"Place bid":"Place order";swap.disabled=true;return}
if(bid){
if(t.addr===ZERO){swap.textContent="Pick a token to bid for";swap.disabled=true;return}
if((f.addr===ZERO?WETH:f.addr).toLowerCase()===t.addr.toLowerCase()){
swap.textContent="Pick different token";swap.disabled=true;return}
if(!floor){swap.textContent="Set an opening bid";swap.disabled=true;return}
if(floor>sell){swap.textContent="Opening exceeds maximum";swap.disabled=true;return}
if(+dly.value===0){swap.textContent="Choose a bid window";swap.disabled=true;return}
if(sell>fromBalance){swap.textContent="Insufficient balance";swap.disabled=true;return}
swap.textContent=`Bid ${trimAmt(floor,f.dec)} → ${trimAmt(sell,f.dec)} ${f.sym} for ${trimAmt(want,t.dec)} ${t.sym}`;
swap.disabled=false;return;
}
if(f.addr===ZERO&&t.addr===WETH){swap.textContent="Pick different token";swap.disabled=true;return}
if(!dutch&&f.addr===WETH&&t.addr===ZERO){swap.textContent="Pick different token";swap.disabled=true;return}
if(dutch&&floor>want){swap.textContent="Floor exceeds start";swap.disabled=true;return}
if(dutch&&+dly.value===0){swap.textContent="Choose decay duration";swap.disabled=true;return}
if(sell>fromBalance){swap.textContent="Insufficient balance";swap.disabled=true;return}
swap.textContent=dutch
?`Dutch ${trimAmt(sell,f.dec)} ${f.sym} · ${trimAmt(want,t.dec)} → ${trimAmt(floor,t.dec)} ${t.sym}`
:`Place ${fill.value==="1"?"":"all-or-nothing "}order \u2014 ${trimAmt(sell,f.dec)} ${f.sym} \u2192 ${trimAmt(want,t.dec)} ${t.addr===ZERO?"WETH":t.sym}`;
{
const qs=t.addr===ZERO?"ETH":t.sym;
rate.textContent=dutch
?`Falls from ${trimAmt(want,t.dec)} to ${trimAmt(floor,t.dec)} ${qs} over ${rel(+dly.value)}, then rests at ${trimAmt(floor,t.dec)} ${qs} `
+(+dRest.value?`for ${rel(+dRest.value)} and returns to you`:`until you cancel`)
:`${fill.value==="1"?"Fills in any amount":"Fills all at once"} at ${trimAmt(want,t.dec)} ${t.addr===ZERO?"WETH":t.sym} for ${trimAmt(sell,f.dec)} ${f.sym}`
+(+dly.value?`, expiring in ${rel(+dly.value)}`:", and never expires");
}
swap.disabled=false;return;
}
if(tab==="send"){
if(!sendReady){
let n=0n;try{n=parseUnits(amt.value.trim(),TOKENS[fromSel.value].dec)}catch{}
swap.textContent=n>0n?"Name a recipient":"Enter an amount";
swap.disabled=true;return}
if(sendReady.amount>fromBalance){swap.textContent="Insufficient balance";swap.disabled=true;return}
const a=`${trimAmt(sendReady.amount,sendReady.token.dec)} ${sendReady.token.sym}`,dv=+dly.value;
if(dv&&sendTipWei>0n&&sendReady.token.addr===ZERO
&&sendReady.amount+sendTipWei>fromBalance){
swap.textContent="Insufficient ETH for amount + keeper tip";swap.disabled=true;return}
swap.textContent=(dv?`Lock ${a} for ${rel(dv)}`:`Send ${a}`)+` \u2192 ${sendReady.label}`;
swap.disabled=false;return;
}
if(quoting){swap.textContent="Quoting…";swap.disabled=true;return}
if(!last){swap.textContent="Swap";swap.disabled=true;return}
if(last.amountIn>fromBalance){swap.textContent="Insufficient balance";swap.disabled=true;return}
swap.textContent="Swap";swap.disabled=false;
};
syncIcons(); render();
const isRejection=e=>e?.code===4001||/user\s+reject|user\s+denied/i.test(e?.message||"");
const W6963=[];
addEventListener("eip6963:announceProvider",e=>{
const d=e.detail;
if(!d||!d.provider||!d.info||W6963.some(x=>x.info.uuid===d.info.uuid))return;
W6963.push(d)});
const wkScan=()=>{try{dispatchEvent(new Event("eip6963:requestProvider"))}catch{}};
wkScan();
const WC_PID="1e8390ef1c1d8a185e035912a1409749";
const WC_ICON='<svg viewBox="0 0 400 400" fill="none" aria-hidden="true"><circle cx="200" cy="200" r="200" fill="#3396ff"/><path fill="#fff" d="m122.519 148.965c42.791-41.729 112.171-41.729 154.962 0l5.15 5.022c2.14 2.086 2.14 5.469 0 7.555l-17.617 17.18c-1.07 1.043-2.804 1.043-3.874 0l-7.087-6.911c-29.853-29.111-78.253-29.111-108.106 0l-7.59 7.401c-1.07 1.043-2.804 1.043-3.874 0l-17.617-17.18c-2.14-2.086-2.14-5.469 0-7.555zm191.397 35.529 15.679 15.29c2.14 2.086 2.14 5.469 0 7.555l-70.7 68.944c-2.139 2.087-5.608 2.087-7.748 0l-50.178-48.931c-.535-.522-1.402-.522-1.937 0l-50.178 48.931c-2.139 2.087-5.608 2.087-7.748 0l-70.7015-68.945c-2.1396-2.086-2.1396-5.469 0-7.555l15.6795-15.29c2.1396-2.087 5.6085-2.087 7.7481 0l50.1789 48.932c.535.522 1.402.522 1.937 0l50.177-48.932c2.139-2.087 5.608-2.087 7.748 0l50.179 48.932c.535.522 1.402.522 1.937 0l50.179-48.931c2.139-2.087 5.608-2.087 7.748 0z"/></svg>';
const WCU=(()=>{
const rl=(v,c)=>(v<<c|v>>>(32-c))>>>0;
const wds=b=>{const o=[];for(let i=0;i<b.length;i+=4)o.push((b[i]|b[i+1]<<8|b[i+2]<<16|b[i+3]<<24)>>>0);return o};
function cblk(x,k,n,c){
const s=[0x61707865,0x3320646e,0x79622d32,0x6b206574,
k[0],k[1],k[2],k[3],k[4],k[5],k[6],k[7],c,n[0],n[1],n[2]];
for(let i=0;i<16;i++)x[i]=s[i];
for(let r=0;r<10;r++){
const q=(a,b,cc,d)=>{
x[a]=(x[a]+x[b])>>>0;x[d]=rl(x[d]^x[a],16);
x[cc]=(x[cc]+x[d])>>>0;x[b]=rl(x[b]^x[cc],12);
x[a]=(x[a]+x[b])>>>0;x[d]=rl(x[d]^x[a],8);
x[cc]=(x[cc]+x[d])>>>0;x[b]=rl(x[b]^x[cc],7)};
q(0,4,8,12);q(1,5,9,13);q(2,6,10,14);q(3,7,11,15);
q(0,5,10,15);q(1,6,11,12);q(2,7,8,13);q(3,4,9,14);}
for(let i=0;i<16;i++)x[i]=(x[i]+s[i])>>>0;}
function chacha(key,nonce,ctr,src){
const k=wds(key),n=wds(nonce),x=new Uint32Array(16),out=new Uint8Array(src.length);
for(let p=0;p<src.length;p+=64){cblk(x,k,n,ctr++);
for(let i=0;i<64&&p+i<src.length;i++)out[p+i]=src[p+i]^(x[i>>2]>>>((i&3)*8)&255);}
return out}
function poly(msg,key){
const P=(1n<<130n)-5n;
let r=0n,sk=0n;
for(let i=15;i>=0;i--)r=(r<<8n)|BigInt(key[i]);
r&=0x0ffffffc0ffffffc0ffffffc0fffffffn;
for(let i=31;i>=16;i--)sk=(sk<<8n)|BigInt(key[i]);
let a=0n;
for(let i=0;i<msg.length;i+=16){
const n=Math.min(16,msg.length-i);
let b=0n;
for(let j=n-1;j>=0;j--)b=(b<<8n)|BigInt(msg[i+j]);
a=((a+b+(1n<<BigInt(8*n)))*r)%P;}
a=(a+sk)&((1n<<128n)-1n);
const o=new Uint8Array(16);
for(let i=0;i<16;i++){o[i]=Number(a&255n);a>>=8n}
return o}
const p16=n=>n%16?16-n%16:0;
const le64=n=>{const b=new Uint8Array(8);for(let i=0;i<8;i++){b[i]=n&255;n=Math.floor(n/256)}return b};
function tagOf(ct,key,nonce){
const otk=chacha(key,nonce,0,new Uint8Array(32));
const pad=new Uint8Array(p16(ct.length));
const m=new Uint8Array(ct.length+pad.length+16);
m.set(ct);m.set(pad,ct.length);
m.set(le64(0),ct.length+pad.length);m.set(le64(ct.length),ct.length+pad.length+8);
return poly(m,otk)}
const seal=(key,nonce,pt)=>{
const ct=chacha(key,nonce,1,pt),tg=tagOf(ct,key,nonce);
const o=new Uint8Array(ct.length+16);o.set(ct);o.set(tg,ct.length);return o};
const open=(key,nonce,box)=>{
if(box.length<16)return null;
const ct=box.subarray(0,box.length-16),tg=box.subarray(box.length-16);
const w=tagOf(ct,key,nonce);
let bad=0;for(let i=0;i<16;i++)bad|=w[i]^tg[i];
return bad?null:chacha(key,nonce,1,ct)};
const hex=b=>{let s="";for(const x of b)s+=x.toString(16).padStart(2,"0");return s};
const unhex=h=>{const b=new Uint8Array(h.length/2);
for(let i=0;i<b.length;i++)b[i]=parseInt(h.substr(i*2,2),16);return b};
const bin=b=>{let s="";for(let i=0;i<b.length;i+=4096)s+=String.fromCharCode.apply(null,b.subarray(i,i+4096));return s};
const b64=b=>btoa(bin(b));
const unb64=s=>{const t=atob(s),b=new Uint8Array(t.length);
for(let i=0;i<t.length;i++)b[i]=t.charCodeAt(i);return b};
const b64u=b=>b64(b).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"");
const utf8=s=>new TextEncoder().encode(s);
const B58="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
const b58=b=>{let n=0n;for(const x of b)n=n*256n+BigInt(x);
let s="";while(n>0n){s=B58[Number(n%58n)]+s;n/=58n}
for(const x of b){if(x)break;s="1"+s}return s};
const rnd=n=>crypto.getRandomValues(new Uint8Array(n));
const sha256=async b=>new Uint8Array(await crypto.subtle.digest("SHA-256",b));
const topicOf=async k=>hex(await sha256(k));
const encode=(symKey,payload,senderPub)=>{
const iv=rnd(12),pt=utf8(JSON.stringify(payload));
const sealed=seal(symKey,iv,pt);
const t=senderPub?1:0;
const head=senderPub?1+32:1;
const out=new Uint8Array(head+12+sealed.length);
out[0]=t;
if(senderPub)out.set(senderPub,1);
out.set(iv,head);out.set(sealed,head+12);
return b64(out)};
const decode=(symKey,msg)=>{
let b;try{b=unb64(msg)}catch{return null}
if(!b.length)return null;
const t=b[0];
if(t!==0&&t!==1)return null;
const head=t===1?33:1;
if(b.length<head+12+16)return null;
const iv=b.subarray(head,head+12),box=b.subarray(head+12);
const pt=open(symKey,iv,box);
if(!pt)return null;
try{return JSON.parse(new TextDecoder().decode(pt))}catch{return null}};
const didKey=pub=>{const b=new Uint8Array(34);b[0]=0xed;b[1]=0x01;b.set(pub,2);
return"did:key:z"+b58(b)};
async function relayJwt(aud){
let kp;
try{kp=await crypto.subtle.generateKey({name:"Ed25519"},true,["sign","verify"])}
catch{throw Error("This browser cannot do Ed25519. WalletConnect needs a newer "
+"browser; an extension wallet works here today.")}
const pub=new Uint8Array(await crypto.subtle.exportKey("raw",kp.publicKey));
const iss=didKey(pub);
const iat=Math.floor(Date.now()/1e3);
const h=b64u(utf8(JSON.stringify({alg:"EdDSA",typ:"JWT"})));
const p=b64u(utf8(JSON.stringify({iss,sub:hex(rnd(32)),aud,iat,exp:iat+86400})));
const sig=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},kp.privateKey,utf8(h+"."+p)));
return h+"."+p+"."+b64u(sig)}
async function kex(){
let kp;
try{kp=await crypto.subtle.generateKey({name:"X25519"},true,["deriveBits"])}
catch{throw Error("This browser cannot do X25519. WalletConnect needs a newer "
+"browser; an extension wallet works here today.")}
const pub=new Uint8Array(await crypto.subtle.exportKey("raw",kp.publicKey));
return{priv:kp.privateKey,pub}}
async function sessionKey(priv,peerHex){
const peer=await crypto.subtle.importKey("raw",unhex(peerHex),{name:"X25519"},false,[]);
const bits=new Uint8Array(await crypto.subtle.deriveBits({name:"X25519",public:peer},priv,256));
const hk=await crypto.subtle.importKey("raw",bits,"HKDF",false,["deriveBits"]);
const out=await crypto.subtle.deriveBits(
{name:"HKDF",hash:"SHA-256",salt:new Uint8Array(0),info:new Uint8Array(0)},hk,256);
return new Uint8Array(out)}
return{seal,open,chacha,poly,hex,unhex,b64,unb64,b64u,b58,didKey,rnd,sha256,
topicOf,encode,decode,relayJwt,kex,sessionKey};
})();
const WCCLI=(U,WSC)=>{
const RELAY="wss://relay.walletconnect.org";
const T_PROPOSE=1100,T_APPROVE=1101,T_SETTLE=1102,T_SETTLE_RES=1103,T_REQ=1108,T_RES=1109;
const TTL=300,STTL=604800;
let sock=null,nextId=1,waiters={},subs={},onEvent=null,alive=false,gone="";
const rpcId=()=>Date.now()*1000+(nextId++%1000);
const sendRaw=o=>{
if(!alive)throw Error(gone||"The wallet connection is closed.");
sock.send(JSON.stringify(o))};
function drop(why){
if(!alive&&gone)return;
alive=false;gone=why;
const ws=waiters;waiters={};subs={};
for(const k in ws)ws[k].rej(Error(why));
if(onEvent)onEvent({t:"closed",why})}
function relayCall(method,params){
const id=rpcId();
return new Promise((res,rej)=>{
waiters[id]={res,rej};
sendRaw({id,jsonrpc:"2.0",method,params});
setTimeout(()=>{if(waiters[id]){delete waiters[id];rej(Error("relay timeout"))}},15000)})}
function handle(raw){
let m;try{m=JSON.parse(raw)}catch{return}
if(m.method==="irn_subscription"){
if(!alive)return;
sendRaw({id:m.id,jsonrpc:"2.0",result:true});
const d=m.params&&m.params.data;
if(d&&subs[d.topic])Promise.resolve(subs[d.topic](d.message)).catch(()=>{});
return}
if(m.id&&waiters[m.id]){
const w=waiters[m.id];delete waiters[m.id];
if(m.error)w.rej(Error(m.error.message||"relay error"));else w.res(m.result)}}
async function connect(projectId){
try{sock&&sock.close()}catch{}
sock=null;alive=false;gone="";waiters={};subs={};
const jwt=await U.relayJwt(RELAY);
const url=`${RELAY}/?auth=${jwt}&projectId=${projectId}&ua=zswap`;
const ws=WSC(url);
sock=ws;
await new Promise((res,rej)=>{
let d=0;
const t=setTimeout(()=>{if(!d){d=1;rej(Error("The relay did not answer."))}},15000);
const fail=m=>{try{ws.close()}catch{}if(sock===ws)sock=null;rej(Error(m))};
const end=f=>x=>{if(d)return;d=1;clearTimeout(t);f(x)};
sock.onopen=end(()=>{alive=true;res()});
sock.onerror=end(()=>fail("The relay could not be reached."));
sock.onclose=end(e=>fail("The relay closed the connection"
+(e&&e.code?" (code "+e.code+(e.reason?": "+e.reason:"")+")":"")+"."))})
sock.onclose=()=>drop("The relay connection dropped. Reconnect your wallet.");
sock.onmessage=e=>handle(typeof e.data==="string"?e.data:"");
}
const subscribe=async(topic,fn)=>{subs[topic]=fn;await relayCall("irn_subscribe",{topic})};
const publish=(topic,message,tag,ttl)=>
relayCall("irn_publish",{topic,message,ttl:ttl||TTL,tag,prompt:tag===T_PROPOSE||tag===T_REQ});
async function pair(projectId,meta){
await connect(projectId);
const symKey=U.rnd(32);
const pTopic=await U.topicOf(symKey);
const kp=await U.kex();
const proposeId=rpcId();
let settle=null;
const pKey="p"+proposeId;
const done=new Promise((res,rej)=>{settle={
res:v=>{delete waiters[pKey];res(v)},
rej:e=>{delete waiters[pKey];rej(e)}}});
waiters[pKey]={res:v=>settle.res(v),rej:e=>settle.rej(e)};
await subscribe(pTopic,async msg=>{
try{
const m=U.decode(symKey,msg);
if(!m||m.id!==proposeId)return;
if(m.error)return settle.rej(Error(m.error.message||"rejected"));
const rp=m.result&&m.result.responderPublicKey;
if(!rp)return;
const sKey=await U.sessionKey(kp.priv,rp);
const sTopic=await U.topicOf(sKey);
await subscribe(sTopic,async smsg=>{
const s=U.decode(sKey,smsg);
if(!s)return;
if(s.method==="wc_sessionSettle"){
await publish(sTopic,U.encode(sKey,{id:s.id,jsonrpc:"2.0",result:true}),T_SETTLE_RES,STTL);
const ns=s.params&&s.params.namespaces||{};
const accts=[];
for(const k in ns)for(const a of ns[k].accounts||[])accts.push(a);
settle.res({topic:sTopic,key:sKey,accounts:accts,
methods:(ns.eip155&&ns.eip155.methods)||[]});
return}
if(s.method==="wc_sessionDelete")return drop("The wallet ended the session.");
if(s.method&&onEvent)onEvent({t:"session",m:s});
if(s.id&&waiters["s"+s.id]){
const w=waiters["s"+s.id];delete waiters["s"+s.id];
if(s.error)w.rej(Object.assign(Error(s.error.message||"rejected"),{code:s.error.code}));
else w.res(s.result)}});
}catch(e){settle.rej(e instanceof Error?e:Error(String(e)))}
});
const proposal={id:proposeId,jsonrpc:"2.0",method:"wc_sessionPropose",params:{
relays:[{protocol:"irn"}],
proposer:{publicKey:U.hex(kp.pub),metadata:meta},
requiredNamespaces:{},
optionalNamespaces:{eip155:{chains:Object.keys(CHAINS).map(id=>"eip155:"+id),
methods:["eth_sendTransaction","personal_sign","eth_signTypedData_v4",
"eth_call","eth_chainId","eth_accounts","eth_getBalance",
"wallet_switchEthereumChain","wallet_addEthereumChain"],
events:["chainChanged","accountsChanged"]}}}};
await publish(pTopic,U.encode(symKey,proposal),T_PROPOSE);
const uri=`wc:${pTopic}@2?relay-protocol=irn&symKey=${U.hex(symKey)}`;
return{uri,done}}
function request(sess,method,params){
const id=rpcId();
const body={id,jsonrpc:"2.0",method:"wc_sessionRequest",
params:{request:{method,params:params||[]},chainId:"eip155:1"}};
const p=new Promise((res,rej)=>{
waiters["s"+id]={res,rej};
setTimeout(()=>{if(waiters["s"+id]){delete waiters["s"+id];rej(Error("wallet timed out"))}},300000)});
publish(sess.topic,U.encode(sess.key,body),T_REQ).catch(e=>{
const w=waiters["s"+id];if(!w)return;delete waiters["s"+id];w.rej(e)});
return p}
return{pair,request,close:()=>{drop("The wallet connection was closed.");try{sock&&sock.close()}catch{}sock=null},
on:f=>{onEvent=f},_relayCall:relayCall};
};
const QR8=(()=>{
const EXP=new Uint8Array(512),LOG=new Uint8Array(256);
(()=>{let x=1;for(let i=0;i<255;i++){EXP[i]=x;LOG[x]=i;x<<=1;if(x&256)x^=285}
for(let i=255;i<512;i++)EXP[i]=EXP[i-255]})();
const mul=(a,b)=>a&&b?EXP[LOG[a]+LOG[b]]:0;
const gen=n=>{let p=[1];
for(let i=0;i<n;i++){const q=new Array(p.length+1).fill(0);
for(let j=0;j<p.length;j++){q[j]^=mul(p[j],EXP[i]);q[j+1]^=p[j]}p=q}
return p};
const rs=(data,n)=>{
const g=gen(n),r=new Uint8Array(data.length+n);
r.set(data);
for(let i=0;i<data.length;i++){
const c=r[i];if(!c)continue;
for(let j=0;j<=n;j++)r[i+j]^=mul(g[n-j],c)}
return r.subarray(data.length)};
const SZ=49,NBLK=2,DPB=97,ECB=24,ALIGN=[6,24,42];
const bch=(v,g,n)=>{let d=v<<n;
const bits=x=>{let c=0;while(x){c++;x>>>=1}return c};
const gl=bits(g);
while(bits(d)>=gl)d^=g<<(bits(d)-gl);
return d};
const fmtBits=mask=>{
const v=(1<<3)|mask;
return ((v<<10)|bch(v,0x537,10))^0x5412};
const verBits=()=>(8<<12)|bch(8,0x1f25,12);
function encode(str){
const bytes=new TextEncoder().encode(str);
if(bytes.length>NBLK*DPB-2)throw Error("pairing code too long to draw");
const bits=[];
const push=(v,n)=>{for(let i=n-1;i>=0;i--)bits.push((v>>i)&1)};
push(4,4);push(bytes.length,8);
for(const b of bytes)push(b,8);
const cap=(NBLK*DPB)*8;
for(let i=0;i<4&&bits.length<cap;i++)bits.push(0);
while(bits.length%8)bits.push(0);
const cw=[];
for(let i=0;i<bits.length;i+=8){let v=0;for(let j=0;j<8;j++)v=(v<<1)|bits[i+j];cw.push(v)}
const pads=[0xec,0x11];
for(let i=0;cw.length<NBLK*DPB;i++)cw.push(pads[i%2]);
const blocks=[],ecs=[];
for(let i=0;i<NBLK;i++){
const d=Uint8Array.from(cw.slice(i*DPB,(i+1)*DPB));
blocks.push(d);ecs.push(rs(d,ECB))}
const out=[];
for(let i=0;i<DPB;i++)for(const b of blocks)out.push(b[i]);
for(let i=0;i<ECB;i++)for(const e of ecs)out.push(e[i]);
return out}
function frame(){
const m=[],fn=[];
for(let i=0;i<SZ;i++){m.push(new Array(SZ).fill(0));fn.push(new Array(SZ).fill(0))}
const put=(r,c,v)=>{m[r][c]=v;fn[r][c]=1};
const finder=(r,c)=>{
for(let i=-1;i<8;i++)for(let j=-1;j<8;j++){
const rr=r+i,cc=c+j;
if(rr<0||cc<0||rr>=SZ||cc>=SZ)continue;
const on=(i>=0&&i<=6&&(j===0||j===6))||(j>=0&&j<=6&&(i===0||i===6))||(i>=2&&i<=4&&j>=2&&j<=4);
put(rr,cc,on?1:0)}};
finder(0,0);finder(0,SZ-7);finder(SZ-7,0);
for(const r of ALIGN)for(const c of ALIGN){
if((r===6&&c===6)||(r===6&&c===ALIGN[ALIGN.length-1])||(r===ALIGN[ALIGN.length-1]&&c===6))continue;
for(let i=-2;i<=2;i++)for(let j=-2;j<=2;j++)
put(r+i,c+j,(Math.abs(i)===2||Math.abs(j)===2||(i===0&&j===0))?1:0)}
for(let i=8;i<SZ-8;i++){put(6,i,i%2?0:1);put(i,6,i%2?0:1)}
put(SZ-8,8,1);
for(let i=0;i<9;i++){if(!fn[8][i])put(8,i,0);if(!fn[i][8])put(i,8,0)}
for(let i=0;i<8;i++){if(!fn[8][SZ-1-i])put(8,SZ-1-i,0);if(!fn[SZ-1-i][8])put(SZ-1-i,8,0)}
const vb=verBits();
for(let i=0;i<18;i++){
const b=(vb>>i)&1,r=Math.floor(i/3),c=i%3;
put(SZ-11+c,r,b);put(r,SZ-11+c,b)}
return{m,fn}}
function place(m,fn,cw){
let bit=0,up=1;
const get=i=>(cw[i>>3]>>(7-(i&7)))&1;
for(let c=SZ-1;c>0;c-=2){
if(c===6)c--;
for(let k=0;k<SZ;k++){
const r=up?SZ-1-k:k;
for(let j=0;j<2;j++){
const cc=c-j;
if(fn[r][cc])continue;
m[r][cc]=bit<cw.length*8?get(bit):0;bit++}}
up^=1}}
const maskFn=(k,r,c)=>[
(r+c)%2===0,r%2===0,c%3===0,(r+c)%3===0,
(((r/2)|0)+((c/3)|0))%2===0,((r*c)%2+(r*c)%3)===0,
(((r*c)%2+(r*c)%3)%2)===0,(((r+c)%2+(r*c)%3)%2)===0][k];
function penalty(m){
let p=0;
for(let i=0;i<SZ;i++){
let rc=1,cc=1;
for(let j=1;j<SZ;j++){
rc=m[i][j]===m[i][j-1]?rc+1:1;if(rc===5)p+=3;else if(rc>5)p++;
cc=m[j][i]===m[j-1][i]?cc+1:1;if(cc===5)p+=3;else if(cc>5)p++}}
for(let i=0;i<SZ-1;i++)for(let j=0;j<SZ-1;j++){
const s=m[i][j]+m[i][j+1]+m[i+1][j]+m[i+1][j+1];
if(s===0||s===4)p+=3}
const pat=[1,0,1,1,1,0,1];
const hit=(get)=>{
for(let i=0;i<SZ;i++)for(let j=0;j<SZ-6;j++){
let okk=1;for(let k=0;k<7;k++)if(get(i,j+k)!==pat[k]){okk=0;break}
if(!okk)continue;
let before=1,after=1;
for(let k=j-4;k<j;k++)if(k<0||get(i,k)!==0){before=0;break}
for(let k=j+7;k<j+11;k++)if(k>=SZ||get(i,k)!==0){after=0;break}
if(before||after)p+=40}};
hit((i,j)=>m[i][j]);hit((i,j)=>m[j][i]);
let dark=0;for(let i=0;i<SZ;i++)for(let j=0;j<SZ;j++)dark+=m[i][j];
p+=Math.floor(Math.abs(dark*100/(SZ*SZ)-50)/5)*10;
return p}
function build(str){
const cw=encode(str);
let best=null,bestP=Infinity,bestK=0;
for(let k=0;k<8;k++){
const{m,fn}=frame();
place(m,fn,cw);
for(let r=0;r<SZ;r++)for(let c=0;c<SZ;c++)
if(!fn[r][c]&&maskFn(k,r,c))m[r][c]^=1;
const f=fmtBits(k);
for(let i=0;i<8;i++){
const b=(f>>i)&1;
if(i<6)m[i][8]=b;else if(i===6)m[7][8]=b;else m[8][8]=b;
m[8][SZ-1-i]=b}
for(let i=8;i<15;i++){
const b=(f>>i)&1,c=14-i;
if(c<6)m[8][c]=b;else m[8][7]=b;
m[SZ-1-c][8]=b}
m[SZ-8][8]=1;
const p=penalty(m);
if(p<bestP){bestP=p;best=m;bestK=k}}
return{size:SZ,modules:best,mask:bestK}}
return{build,_encode:encode};
})();
const wcNode=()=>rpcPin()||rpcPool[rpcPi];
const wcHost=()=>{try{return new URL(wcNode()).host}catch{return wcNode()}};
const WC_SIGN=["eth_sendTransaction","eth_signTransaction","personal_sign","eth_sign",
"eth_signTypedDa