From 33f11ab488f5454edf207d54fc52d1c09ba3cb4c Mon Sep 17 00:00:00 2001 From: fedellen Date: Wed, 6 Dec 2023 23:35:39 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20ardrivea?= =?UTF-8?q?pp/turbo-app@5e88682ad0fa51964acec3ca4cfcb91bd79f365f=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/index-ApzE2zbq.css | 1 + assets/index-RMRgo0vt.css | 1 - assets/{index-abJUlCy6.js => index-fGkjx66v.js} | 2 +- index.html | 4 ++-- 4 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 assets/index-ApzE2zbq.css delete mode 100644 assets/index-RMRgo0vt.css rename assets/{index-abJUlCy6.js => index-fGkjx66v.js} (99%) diff --git a/assets/index-ApzE2zbq.css b/assets/index-ApzE2zbq.css new file mode 100644 index 0000000..da5c464 --- /dev/null +++ b/assets/index-ApzE2zbq.css @@ -0,0 +1 @@ +#root{max-width:1280px;margin:0 auto;padding:2rem;text-align:center;font-family:Wavehaus-Book;display:flex;flex-direction:column;align-items:center;justify-content:center}.ardrive-logo:hover{filter:drop-shadow(0 0 2em var(--ardrive-red))}.alert{margin:1rem 0;padding:1rem 2rem;border-radius:.5rem;font-size:1rem;font-family:Wavehaus-Extra;color:var(--ardrive-red)}.gift-form{display:flex;flex-direction:column;align-items:center;justify-content:center;margin:2rem;max-width:40rem}.gift-form h1{font-family:Wavehaus-Extra;font-size:2.15rem;margin:3rem 2rem}.form-section{display:flex;flex-direction:column;align-items:left;margin:.5rem 1rem;width:100%}.form-label{margin:.5rem;font-size:1.25rem;font-weight:700;font-family:Wavehaus-Bold;text-align:left;font-size:1rem}.form-input{width:100%;margin:.5rem 0;padding:.5rem 1rem;border:1px solid var(--off-gray);border-radius:.5rem;font-size:1.2rem;font-family:Wavehaus-Semi;box-sizing:border-box;background-color:var(--dark-gray)}#recipient-email:not(:focus):not(:placeholder-shown):invalid{border-color:var(--ardrive-red)}#usd-form-input{display:flex;background-color:var(--dark-gray);width:100%;border:1px solid var(--off-gray);border-radius:.5rem}#dollar-sign{font-family:Wavehaus-Semi;font-size:1.2rem;padding:.5rem 1rem;border:none}#usd-input{font-family:Wavehaus-Semi;font-size:1.2rem;width:100%;margin:.5rem;border:none;background-color:var(--dark-gray)}.form-input:focus,#usd-input:focus,#usd-form-input:focus-within{outline:none;border-color:var(--white);border-width:.1rem}#conversions{margin:2rem 0;font-family:Wavehaus-Semi;font-size:1.5rem}.conversion-amount{font-family:Wavehaus-Semi;font-size:1.75rem;margin:.25rem}#gift-message{min-height:10rem;resize:none}.terms-and-conditions{display:flex;margin:1rem 0;font-size:1rem;font-family:Wavehaus-Semi}.terms-and-conditions a{color:var(--ardrive-red);font-family:Wavehaus-Bold}.terms-and-conditions a:hover{color:var(--ardrive-red);text-decoration:underline}a{color:var(--ardrive-red);text-decoration:inherit}a:hover{text-decoration:underline}input[type=checkbox]{width:1.5rem;height:1.5rem;-webkit-appearance:none;-moz-appearance:none;appearance:none;outline:none;border-radius:.25rem;border:.1rem solid var(--gray)}input[type=checkbox]:checked{background-color:var(--ardrive-red);border:none}input[type=checkbox]:hover{cursor:pointer}input[type=checkbox]:checked:before{content:"✓";font-size:1.35rem;color:var(--white);position:absolute;transform:translate(20%,-5%)}#terms-and-conditions-checkbox{margin:0 .75rem}#gift-form-submit-button{margin:2rem;padding:1rem 1.25rem;border:none;border-radius:3rem;background-color:var(--ardrive-red);color:var(--white);font-size:1.25rem;font-family:Wavehaus-Bold;cursor:pointer}#gift-form-submit-button:hover{background-color:var(--ardrive-red)}#gift-form-submit-button:disabled{background-color:var(--off-gray);cursor:not-allowed}@media (prefers-color-scheme: light){.form-input,#usd-input,#usd-form-input{background-color:var(--white)}.form-input:focus,#usd-input:focus,#usd-form-input:focus-within{border-color:var(--black)}}:root{font-family:Wavehaus-Semi,sans-serif;line-height:1.5;font-weight:400;color-scheme:light dark;color:var(--text-white);background-color:var(--black);font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--ardrive-red: #d31721;--text-white: #a6a6a6;--white: #fafafa;--black: #0d0d0d;--dark-gray: #171717;--gray: #7d7d7d;--off-gray: #787878}input[type=number]{-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}@media (prefers-color-scheme: light){:root{color:var(--black);background-color:var(--white)}} diff --git a/assets/index-RMRgo0vt.css b/assets/index-RMRgo0vt.css deleted file mode 100644 index 6a30955..0000000 --- a/assets/index-RMRgo0vt.css +++ /dev/null @@ -1 +0,0 @@ -#root{max-width:1280px;margin:0 auto;padding:2rem;text-align:center;font-family:Wavehaus-Book;display:flex;flex-direction:column;align-items:center;justify-content:center}.ardrive-logo:hover{filter:drop-shadow(0 0 2em var(--ardrive-red))}.alert{margin:1rem 0;padding:1rem 2rem;border-radius:.5rem;font-size:1rem;font-family:Wavehaus-Extra;color:var(--ardrive-red)}.gift-form{display:flex;flex-direction:column;align-items:center;justify-content:center;margin:2rem;max-width:40rem}.gift-form h1{font-family:Wavehaus-Extra;font-size:2.15rem;margin:3rem 2rem}.form-section{display:flex;flex-direction:column;align-items:left;margin:.5rem 1rem;width:100%}.form-label{margin:.5rem;font-size:1.25rem;font-weight:700;font-family:Wavehaus-Bold;text-align:left;font-size:1rem}.form-input{width:100%;margin:.5rem 0;padding:.5rem 1rem;border:1px solid var(--off-gray);border-radius:.5rem;font-size:1.2rem;font-family:Wavehaus-Semi;box-sizing:border-box;background-color:var(--dark-gray)}#recipient-email:not(:focus):not(:placeholder-shown):invalid{border-color:var(--ardrive-red)}#usd-form-input{display:flex;background-color:var(--dark-gray);width:100%;border:1px solid var(--off-gray);border-radius:.5rem}#dollar-sign{font-family:Wavehaus-Semi;font-size:1.2rem;padding:.5rem 1rem;border:none}#usd-input{font-family:Wavehaus-Semi;font-size:1.2rem;width:100%;margin:.5rem;border:none;background-color:var(--dark-gray)}.form-input:focus,#usd-input:focus,#usd-form-input:focus-within{outline:none;border-color:var(--white);border-width:.1rem}#conversions{margin:2rem 0;font-family:Wavehaus-Semi;font-size:1.5rem}.conversion-amount{font-family:Wavehaus-Semi;font-size:1.75rem;margin:.25rem}textarea{min-height:10rem}.terms-and-conditions{display:flex;margin:1rem 0;font-size:1rem;font-family:Wavehaus-Semi}.terms-and-conditions a{color:var(--ardrive-red);font-family:Wavehaus-Bold}.terms-and-conditions a:hover{color:var(--ardrive-red);text-decoration:underline}a{color:var(--ardrive-red);text-decoration:inherit}a:hover{text-decoration:underline}input[type=checkbox]{width:1.5rem;height:1.5rem;-webkit-appearance:none;-moz-appearance:none;appearance:none;outline:none;border-radius:.25rem;border:.1rem solid var(--gray)}input[type=checkbox]:checked{background-color:var(--ardrive-red);border:none}input[type=checkbox]:hover{cursor:pointer}input[type=checkbox]:checked:before{content:"✓";font-size:1.35rem;color:var(--white);position:absolute;transform:translate(20%,-5%)}#terms-and-conditions-checkbox{margin:0 .75rem}#gift-form-submit-button{margin:2rem;padding:1rem 1.25rem;border:none;border-radius:3rem;background-color:var(--ardrive-red);color:var(--white);font-size:1.25rem;font-family:Wavehaus-Bold;cursor:pointer}#gift-form-submit-button:hover{background-color:var(--ardrive-red)}#gift-form-submit-button:disabled{background-color:var(--off-gray);cursor:not-allowed}@media (prefers-color-scheme: light){.form-input,#usd-input,#usd-form-input{background-color:var(--white)}.form-input:focus,#usd-input:focus,#usd-form-input:focus-within{border-color:var(--black)}}:root{font-family:Wavehaus-Semi,sans-serif;line-height:1.5;font-weight:400;color-scheme:light dark;color:var(--text-white);background-color:var(--black);font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--ardrive-red: #d31721;--text-white: #a6a6a6;--white: #fafafa;--black: #0d0d0d;--dark-gray: #171717;--gray: #7d7d7d;--off-gray: #787878}input[type=number]{-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}@media (prefers-color-scheme: light){:root{color:var(--black);background-color:var(--white)}} diff --git a/assets/index-abJUlCy6.js b/assets/index-fGkjx66v.js similarity index 99% rename from assets/index-abJUlCy6.js rename to assets/index-fGkjx66v.js index a1eea1f..bf66a9e 100644 --- a/assets/index-abJUlCy6.js +++ b/assets/index-fGkjx66v.js @@ -175,4 +175,4 @@ nonce: bundlr`),Te.Buffer.from(a))}}class jR{constructor(t,r){Pe(this,"_publicKe -----END RSA `+n+` KEY----- `,f=Te.Buffer.alloc(0);r?(t.version="two-prime",f=YR.encode(t,"der")):f=VR.encode(t,"der");var l=f.toString("base64").match(/.{1,64}/g).join(` `);return a+l+i}Js.jwkTopem=NJ;var DJ=Oe&&Oe.__createBinding||(Object.create?function(e,t,r,n){n===void 0&&(n=r);var a=Object.getOwnPropertyDescriptor(t,r);(!a||("get"in a?!t.__esModule:a.writable||a.configurable))&&(a={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,a)}:function(e,t,r,n){n===void 0&&(n=r),e[n]=t[r]}),FJ=Oe&&Oe.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),UJ=Oe&&Oe.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)r!=="default"&&Object.prototype.hasOwnProperty.call(e,r)&&DJ(t,e,r);return FJ(t,e),t};Object.defineProperty(av,"__esModule",{value:!0});const sx=Js,qn=UJ(c7());class jJ{constructor(){Pe(this,"keyLength",4096);Pe(this,"publicExponent",65537);Pe(this,"hashAlgorithm","sha256");Pe(this,"encryptionAlgorithm","aes-256-cbc")}generateJWK(){if(typeof qn.generateKeyPair!="function")throw new Error("Keypair generation not supported in this version of Node, only supported in versions 10+");return new Promise((t,r)=>{qn.generateKeyPair("rsa",{modulusLength:this.keyLength,publicExponent:this.publicExponent,privateKeyEncoding:{type:"pkcs1",format:"pem"},publicKeyEncoding:{type:"pkcs1",format:"pem"}},(n,a,i)=>{n&&r(n),t(this.pemToJWK(i))})})}sign(t,r,{saltLength:n}={}){return new Promise((a,i)=>{a(qn.createSign(this.hashAlgorithm).update(r).sign({key:this.jwkToPem(t),padding:qn.constants.RSA_PKCS1_PSS_PADDING,saltLength:n}))})}verify(t,r,n){return new Promise((a,i)=>{const f={kty:"RSA",e:"AQAB",n:t},l=this.jwkToPem(f);a(qn.createVerify(this.hashAlgorithm).update(r).verify({key:l,padding:qn.constants.RSA_PKCS1_PSS_PADDING},n))})}hash(t,r="SHA-256"){if(typeof t=="string")throw new TypeError("Data must be a Uint8Array");return new Promise((n,a)=>{n(qn.createHash(this.parseHashAlgorithm(r)).update(t).digest())})}async encrypt(t,r,n){const a=qn.pbkdf2Sync(r,n=n||"salt",1e5,32,this.hashAlgorithm),i=qn.randomBytes(16),f=qn.createCipheriv(this.encryptionAlgorithm,a,i);return Te.Buffer.concat([i,f.update(t),f.final()])}async decrypt(t,r,n){try{const a=qn.pbkdf2Sync(r,n=n||"salt",1e5,32,this.hashAlgorithm),i=t.slice(0,16),f=t.slice(16),l=qn.createDecipheriv(this.encryptionAlgorithm,a,i);return Te.Buffer.concat([l.update(f),l.final()])}catch{throw new Error("Failed to decrypt")}}jwkToPem(t){return(0,sx.jwkTopem)(t)}pemToJWK(t){return(0,sx.pemTojwk)(t)}parseHashAlgorithm(t){switch(t){case"SHA-256":return"sha256";case"SHA-384":return"sha384";default:throw new Error(`Algorithm not supported: ${t}`)}}}av.default=jJ;var sv={};Object.defineProperty(sv,"__esModule",{value:!0});class qJ{constructor(t){Pe(this,"api");this.api=t}getInfo(){return this.api.get("info").then(t=>t.data)}getPeers(){return this.api.get("peers").then(t=>t.data)}}sv.default=qJ;var _c={},qo={};Object.defineProperty(qo,"__esModule",{value:!0});qo.getError=void 0;class zJ extends Error{constructor(r,n={}){var t=(...args)=>{super(...args);Pe(this,"type");Pe(this,"response")};n.message?t(n.message):t(),this.type=r,this.response=n.response}getType(){return this.type}}qo.default=zJ;function $J(e){let t=e.data;if(typeof e.data=="string")try{t=JSON.parse(e.data)}catch{}if(e.data instanceof ArrayBuffer||e.data instanceof Uint8Array)try{t=JSON.parse(t.toString())}catch{}return t?t.error||t:e.statusText||"unknown"}qo.getError=$J;var $f={},_t={},HJ=Oe&&Oe.__createBinding||(Object.create?function(e,t,r,n){n===void 0&&(n=r);var a=Object.getOwnPropertyDescriptor(t,r);(!a||("get"in a?!t.__esModule:a.writable||a.configurable))&&(a={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,a)}:function(e,t,r,n){n===void 0&&(n=r),e[n]=t[r]}),KJ=Oe&&Oe.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),GJ=Oe&&Oe.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)r!=="default"&&Object.prototype.hasOwnProperty.call(e,r)&&HJ(t,e,r);return KJ(t,e),t};Object.defineProperty(_t,"__esModule",{value:!0});_t.b64UrlDecode=_t.b64UrlEncode=fT=_t.bufferTob64Url=_t.bufferTob64=_t.b64UrlToBuffer=_t.stringToB64Url=_t.stringToBuffer=_t.bufferToString=_t.b64UrlToString=_t.concatBuffers=void 0;const tT=GJ(r0);function WJ(e){let t=0;for(let a=0;a=e.MAX_CHUNK_SIZE;){let ee=e.MAX_CHUNK_SIZE,G=J.byteLength-e.MAX_CHUNK_SIZE;G>0&&G({type:"leaf",id:await B(await Promise.all([B(K),B(R(te))])),dataHash:K,minByteRange:J,maxByteRange:te})))}e.generateLeaves=l;async function c(N){return(await m(N)).id}e.computeRootHash=c;async function m(N){return await _(await l(await f(N)))}e.generateTree=m;async function g(N){const K=await f(N),J=await l(K),te=await _(J),ee=await S(te),G=K.slice(-1)[0];return G.maxByteRange-G.minByteRange===0&&(K.splice(K.length-1,1),ee.splice(ee.length-1,1)),{data_root:te.id,chunks:K,proofs:ee}}e.generateTransactionChunks=g;async function _(N,K=0){if(N.length<2)return N[0];const J=[];for(let te=0;te{Array.isArray(J)?K.push(...P(J)):K.push(J)}),K}e.arrayFlatten=P;async function I(N,K){return K?{type:"branch",id:await B([await B(N.id),await B(K.id),await B(R(N.maxByteRange))]),byteRange:N.maxByteRange,maxByteRange:K.maxByteRange,leftChild:N,rightChild:K}:N}async function B(N){return Array.isArray(N)&&(N=r.default.utils.concatBuffers(N)),new Uint8Array(await r.default.crypto.hash(N))}function R(N){const K=new Uint8Array(a);for(var J=K.length-1;J>=0;J--){var te=N%256;K[J]=te,N=(N-te)/256}return K}e.intToBuffer=R;function A(N){let K=0;for(var J=0;JN.every((J,te)=>K[te]===J);e.arrayCompare=U;async function V(N,K,J,te,ee){if(te<=0)return!1;if(K>=te)return V(N,0,te-1,te,ee);if(K<0)return V(N,0,0,te,ee);if(ee.length==i+a){const y=ee.slice(0,i),x=ee.slice(y.length,y.length+a),w=await B([await B(y),await B(x)]);return(0,e.arrayCompare)(N,w)?{offset:te-1,leftBound:J,rightBound:te,chunkSize:te-J}:!1}const G=ee.slice(0,i),E=ee.slice(G.length,G.length+i),d=ee.slice(G.length+E.length,G.length+E.length+a),o=A(d),u=ee.slice(G.length+E.length+d.length),p=await B([await B(G),await B(E),await B(d)]);return(0,e.arrayCompare)(N,p)?K ${JSON.stringify(d)}`;return j(E,o)}e.debug=j}(Ip)),Ip}var cx;function uv(){if(cx)return $f;cx=1;var e=Oe&&Oe.__createBinding||(Object.create?function(g,_,S,M){M===void 0&&(M=S);var P=Object.getOwnPropertyDescriptor(_,S);(!P||("get"in P?!_.__esModule:P.writable||P.configurable))&&(P={enumerable:!0,get:function(){return _[S]}}),Object.defineProperty(g,M,P)}:function(g,_,S,M){M===void 0&&(M=S),g[M]=_[S]}),t=Oe&&Oe.__setModuleDefault||(Object.create?function(g,_){Object.defineProperty(g,"default",{enumerable:!0,value:_})}:function(g,_){g.default=_}),r=Oe&&Oe.__importStar||function(g){if(g&&g.__esModule)return g;var _={};if(g!=null)for(var S in g)S!=="default"&&Object.prototype.hasOwnProperty.call(g,S)&&e(_,g,S);return t(_,g),_},n=Oe&&Oe.__importDefault||function(g){return g&&g.__esModule?g:{default:g}};Object.defineProperty($f,"__esModule",{value:!0}),$f.Tag=void 0;const a=r(_t),i=n(XJ()),f=lT();class l{get(_,S){if(!Object.getOwnPropertyNames(this).includes(_))throw new Error(`Field "${_}" is not a property of the Arweave Transaction class.`);if(this[_]instanceof Uint8Array)return S&&S.decode&&S.string?a.bufferToString(this[_]):S&&S.decode&&!S.string?this[_]:a.bufferTob64Url(this[_]);if(this[_]instanceof Array){if((S==null?void 0:S.decode)!==void 0||(S==null?void 0:S.string)!==void 0)throw _==="tags"&&console.warn(`Did you mean to use 'transaction["tags"]' ?`),new Error("Cannot decode or stringify an array.");return this[_]}return S&&S.decode==!0?S&&S.string?a.b64UrlToString(this[_]):a.b64UrlToBuffer(this[_]):this[_]}}class c extends l{constructor(S,M,P=!1){super();Pe(this,"name");Pe(this,"value");this.name=S,this.value=M}}$f.Tag=c;class m extends l{constructor(S={}){super();Pe(this,"format",2);Pe(this,"id","");Pe(this,"last_tx","");Pe(this,"owner","");Pe(this,"tags",[]);Pe(this,"target","");Pe(this,"quantity","0");Pe(this,"data_size","0");Pe(this,"data",new Uint8Array);Pe(this,"data_root","");Pe(this,"reward","0");Pe(this,"signature","");Pe(this,"chunks");Object.assign(this,S),typeof this.data=="string"&&(this.data=a.b64UrlToBuffer(this.data)),S.tags&&(this.tags=S.tags.map(M=>new c(M.name,M.value)))}addTag(S,M){this.tags.push(new c(a.stringToB64Url(S),a.stringToB64Url(M)))}toJSON(){return{format:this.format,id:this.id,last_tx:this.last_tx,owner:this.owner,tags:this.tags,target:this.target,quantity:this.quantity,data:a.bufferTob64Url(this.data),data_size:this.data_size,data_root:this.data_root,data_tree:this.data_tree,reward:this.reward,signature:this.signature}}setOwner(S){this.owner=S}setSignature({id:S,owner:M,reward:P,tags:I,signature:B}){this.id=S,this.owner=M,P&&(this.reward=P),I&&(this.tags=I),this.signature=B}async prepareChunks(S){!this.chunks&&S.byteLength>0&&(this.chunks=await(0,f.generateTransactionChunks)(S),this.data_root=a.bufferTob64Url(this.chunks.data_root)),!this.chunks&&S.byteLength===0&&(this.chunks={chunks:[],data_root:new Uint8Array,proofs:[]},this.data_root="")}getChunk(S,M){if(!this.chunks)throw new Error("Chunks have not been prepared");const P=this.chunks.proofs[S],I=this.chunks.chunks[S];return{data_root:this.data_root,data_size:this.data_size,data_path:a.bufferTob64Url(P.proof),offset:P.offset.toString(),chunk:a.bufferTob64Url(M.slice(I.minByteRange,I.maxByteRange))}}async getSignatureData(){switch(this.format){case 1:let S=this.tags.reduce((P,I)=>a.concatBuffers([P,I.get("name",{decode:!0,string:!1}),I.get("value",{decode:!0,string:!1})]),new Uint8Array);return a.concatBuffers([this.get("owner",{decode:!0,string:!1}),this.get("target",{decode:!0,string:!1}),this.get("data",{decode:!0,string:!1}),a.stringToBuffer(this.quantity),a.stringToBuffer(this.reward),this.get("last_tx",{decode:!0,string:!1}),S]);case 2:this.data_root||await this.prepareChunks(this.data);const M=this.tags.map(P=>[P.get("name",{decode:!0,string:!1}),P.get("value",{decode:!0,string:!1})]);return await(0,i.default)([a.stringToBuffer(this.format.toString()),this.get("owner",{decode:!0,string:!1}),this.get("target",{decode:!0,string:!1}),a.stringToBuffer(this.quantity),a.stringToBuffer(this.reward),this.get("last_tx",{decode:!0,string:!1}),M,a.stringToBuffer(this.data_size),this.get("data_root",{decode:!0,string:!1})]);default:throw new Error(`Unexpected transaction format: ${this.format}`)}}}return $f.default=m,$f}var z0={},hx;function YJ(){if(hx)return z0;hx=1;var e=Oe&&Oe.__createBinding||(Object.create?function(S,M,P,I){I===void 0&&(I=P);var B=Object.getOwnPropertyDescriptor(M,P);(!B||("get"in B?!M.__esModule:B.writable||B.configurable))&&(B={enumerable:!0,get:function(){return M[P]}}),Object.defineProperty(S,I,B)}:function(S,M,P,I){I===void 0&&(I=P),S[I]=M[P]}),t=Oe&&Oe.__setModuleDefault||(Object.create?function(S,M){Object.defineProperty(S,"default",{enumerable:!0,value:M})}:function(S,M){S.default=M}),r=Oe&&Oe.__importStar||function(S){if(S&&S.__esModule)return S;var M={};if(S!=null)for(var P in S)P!=="default"&&Object.prototype.hasOwnProperty.call(S,P)&&e(M,S,P);return t(M,S),M},n=Oe&&Oe.__importDefault||function(S){return S&&S.__esModule?S:{default:S}};Object.defineProperty(z0,"__esModule",{value:!0}),z0.TransactionUploader=void 0;const a=n(uv()),i=r(_t),f=qo,l=lT(),c=1,m=["invalid_json","chunk_too_big","data_path_too_big","offset_too_big","data_size_too_big","chunk_proof_ratio_not_attractive","invalid_proof"],g=1e3*40;class _{constructor(M,P){Pe(this,"api");Pe(this,"chunkIndex",0);Pe(this,"txPosted",!1);Pe(this,"transaction");Pe(this,"lastRequestTimeEnd",0);Pe(this,"totalErrors",0);Pe(this,"data");Pe(this,"lastResponseStatus",0);Pe(this,"lastResponseError","");if(this.api=M,!P.id)throw new Error("Transaction is not signed");if(!P.chunks)throw new Error("Transaction chunks not prepared");this.data=P.data,this.transaction=new a.default(Object.assign({},P,{data:new Uint8Array(0)}))}get isComplete(){return this.txPosted&&this.chunkIndex===this.transaction.chunks.chunks.length}get totalChunks(){return this.transaction.chunks.chunks.length}get uploadedChunks(){return this.chunkIndex}get pctComplete(){return Math.trunc(this.uploadedChunks/this.totalChunks*100)}async uploadChunk(M){if(this.isComplete)throw new Error("Upload is already complete");if(this.lastResponseError!==""?this.totalErrors++:this.totalErrors=0,this.totalErrors===100)throw new Error(`Unable to complete upload: ${this.lastResponseStatus}: ${this.lastResponseError}`);let P=this.lastResponseError===""?0:Math.max(this.lastRequestTimeEnd+g-Date.now(),g);if(P>0&&(P=P-P*Math.random()*.3,await new Promise(A=>setTimeout(A,P))),this.lastResponseError="",!this.txPosted){await this.postTransaction();return}M&&(this.chunkIndex=M);const I=this.transaction.getChunk(M||this.chunkIndex,this.data);if(!await(0,l.validatePath)(this.transaction.chunks.data_root,parseInt(I.offset),0,parseInt(I.data_size),i.b64UrlToBuffer(I.data_path)))throw new Error(`Unable to validate chunk ${this.chunkIndex}`);const R=await this.api.post("chunk",this.transaction.getChunk(this.chunkIndex,this.data)).catch(A=>(console.error(A.message),{status:-1,data:{error:A.message}}));if(this.lastRequestTimeEnd=Date.now(),this.lastResponseStatus=R.status,this.lastResponseStatus==200)this.chunkIndex++;else if(this.lastResponseError=(0,f.getError)(R),m.includes(this.lastResponseError))throw new Error(`Fatal error uploading chunk ${this.chunkIndex}: ${this.lastResponseError}`)}static async fromSerialized(M,P,I){if(!P||typeof P.chunkIndex!="number"||typeof P.transaction!="object")throw new Error("Serialized object does not match expected format.");var B=new a.default(P.transaction);B.chunks||await B.prepareChunks(I);const R=new _(M,B);if(R.chunkIndex=P.chunkIndex,R.lastRequestTimeEnd=P.lastRequestTimeEnd,R.lastResponseError=P.lastResponseError,R.lastResponseStatus=P.lastResponseStatus,R.txPosted=P.txPosted,R.data=I,R.transaction.data_root!==P.transaction.data_root)throw new Error("Data mismatch: Uploader doesn't match provided data.");return R}static async fromTransactionId(M,P){const I=await M.get(`tx/${P}`);if(I.status!==200)throw new Error(`Tx ${P} not found: ${I.status}`);const B=I.data;return B.data=new Uint8Array(0),{txPosted:!0,chunkIndex:0,lastResponseError:"",lastRequestTimeEnd:0,lastResponseStatus:0,transaction:B}}toJSON(){return{chunkIndex:this.chunkIndex,transaction:this.transaction,lastRequestTimeEnd:this.lastRequestTimeEnd,lastResponseStatus:this.lastResponseStatus,lastResponseError:this.lastResponseError,txPosted:this.txPosted}}async postTransaction(){if(this.totalChunks<=c){this.transaction.data=this.data;const I=await this.api.post("tx",this.transaction).catch(B=>(console.error(B),{status:-1,data:{error:B.message}}));if(this.lastRequestTimeEnd=Date.now(),this.lastResponseStatus=I.status,this.transaction.data=new Uint8Array(0),I.status>=200&&I.status<300){this.txPosted=!0,this.chunkIndex=c;return}throw this.lastResponseError=(0,f.getError)(I),new Error(`Unable to upload transaction: ${I.status}, ${this.lastResponseError}`)}const P=await this.api.post("tx",this.transaction);if(this.lastRequestTimeEnd=Date.now(),this.lastResponseStatus=P.status,!(P.status>=200&&P.status<300))throw this.lastResponseError=(0,f.getError)(P),new Error(`Unable to upload transaction: ${P.status}, ${this.lastResponseError}`);this.txPosted=!0}}return z0.TransactionUploader=_,z0}var dx;function JJ(){if(dx)return _c;dx=1;var e=Oe&&Oe.__createBinding||(Object.create?function(m,g,_,S){S===void 0&&(S=_);var M=Object.getOwnPropertyDescriptor(g,_);(!M||("get"in M?!g.__esModule:M.writable||M.configurable))&&(M={enumerable:!0,get:function(){return g[_]}}),Object.defineProperty(m,S,M)}:function(m,g,_,S){S===void 0&&(S=_),m[S]=g[_]}),t=Oe&&Oe.__setModuleDefault||(Object.create?function(m,g){Object.defineProperty(m,"default",{enumerable:!0,value:g})}:function(m,g){m.default=g}),r=Oe&&Oe.__importStar||function(m){if(m&&m.__esModule)return m;var g={};if(m!=null)for(var _ in m)_!=="default"&&Object.prototype.hasOwnProperty.call(m,_)&&e(g,m,_);return t(g,m),g},n=Oe&&Oe.__importDefault||function(m){return m&&m.__esModule?m:{default:m}};Object.defineProperty(_c,"__esModule",{value:!0});const a=n(qo),i=n(uv()),f=r(_t),l=YJ();class c{constructor(g,_,S){Pe(this,"api");Pe(this,"crypto");Pe(this,"chunks");this.api=g,this.crypto=_,this.chunks=S}async getTransactionAnchor(){const g=await this.api.get("tx_anchor");if(!g.data.match(/^[a-z0-9_-]{43,}/i)||!g.ok)throw new Error(`Could not getTransactionAnchor. Received: ${g.data}. Status: ${g.status}, ${g.statusText}`);return g.data}async getPrice(g,_){let S=_?`price/${g}/${_}`:`price/${g}`;const M=await this.api.get(S);if(!/^\d+$/.test(M.data)||!M.ok)throw new Error(`Could not getPrice. Received: ${M.data}. Status: ${M.status}, ${M.statusText}`);return M.data}async get(g){const _=await this.api.get(`tx/${g}`);if(_.status==200){const S=parseInt(_.data.data_size);if(_.data.format>=2&&S>0&&S<=1024*1024*12){const M=await this.getData(g);return new i.default({..._.data,data:M})}return new i.default({..._.data,format:_.data.format||1})}throw _.status==404?new a.default("TX_NOT_FOUND"):_.status==410?new a.default("TX_FAILED"):new a.default("TX_INVALID")}fromRaw(g){return new i.default(g)}async search(g,_){return this.api.post("arql",{op:"equals",expr1:g,expr2:_}).then(S=>S.data?S.data:[])}getStatus(g){return this.api.get(`tx/${g}/status`).then(_=>_.status==200?{status:200,confirmed:_.data}:{status:_.status,confirmed:null})}async getData(g,_){let S;try{S=await this.chunks.downloadChunkedData(g)}catch(M){console.error(`Error while trying to download chunked data for ${g}`),console.error(M)}if(!S){console.warn(`Falling back to gateway cache for ${g}`);try{const{data:M,ok:P,status:I,statusText:B}=await this.api.get(`/${g}`,{responseType:"arraybuffer"});if(!P)throw new Error("Bad http status code",{cause:{status:I,statusText:B}});S=M}catch(M){console.error(`Error while trying to download contiguous data from gateway cache for ${g}`),console.error(M)}}if(!S)throw new Error(`${g} data was not found!`);return _&&_.decode&&!_.string?S:_&&_.decode&&_.string?f.bufferToString(S):f.bufferTob64Url(S)}async sign(g,_,S){const P=typeof _=="object"&&(B=>{let R=!0;return["n","e","d","p","q","dp","dq","qi"].map(A=>!(A in B)&&(R=!1)),R})(_),I=typeof arweaveWallet=="object";if(!P&&!I)throw new Error("No valid JWK or external wallet found to sign transaction.");if(P){g.setOwner(_.n);let B=await g.getSignatureData(),R=await this.crypto.sign(_,B,S),A=await this.crypto.hash(R);g.setSignature({id:f.bufferTob64Url(A),owner:_.n,signature:f.bufferTob64Url(R)})}else if(I){try{(await arweaveWallet.getPermissions()).includes("SIGN_TRANSACTION")||await arweaveWallet.connect(["SIGN_TRANSACTION"])}catch{}const B=await arweaveWallet.sign(g,S);g.setSignature({id:B.id,owner:B.owner,reward:B.reward,tags:B.tags,signature:B.signature})}else throw new Error("An error occurred while signing. Check wallet is valid")}async verify(g){const _=await g.getSignatureData(),S=g.get("signature",{decode:!0,string:!1}),M=f.bufferTob64Url(await this.crypto.hash(S));if(g.id!==M)throw new Error("Invalid transaction signature or ID! The transaction ID doesn't match the expected SHA-256 hash of the signature.");return this.crypto.verify(g.owner,_,S)}async post(g){if(typeof g=="string"?g=new i.default(JSON.parse(g)):typeof g.readInt32BE=="function"?g=new i.default(JSON.parse(g.toString())):typeof g=="object"&&!(g instanceof i.default)&&(g=new i.default(g)),!(g instanceof i.default))throw new Error("Must be Transaction object");g.chunks||await g.prepareChunks(g.data);const _=await this.getUploader(g,g.data);try{for(;!_.isComplete;)await _.uploadChunk()}catch(S){if(_.lastResponseStatus>0)return{status:_.lastResponseStatus,statusText:_.lastResponseError,data:{error:_.lastResponseError}};throw S}return{status:200,statusText:"OK",data:{}}}async getUploader(g,_){let S;if(_ instanceof ArrayBuffer&&(_=new Uint8Array(_)),g instanceof i.default){if(_||(_=g.data),!(_ instanceof Uint8Array))throw new Error("Data format is invalid");g.chunks||await g.prepareChunks(_),S=new l.TransactionUploader(this.api,g),(!S.data||S.data.length===0)&&(S.data=_)}else{if(typeof g=="string"&&(g=await l.TransactionUploader.fromTransactionId(this.api,g)),!_||!(_ instanceof Uint8Array))throw new Error("Must provide data when resuming upload");S=await l.TransactionUploader.fromSerialized(this.api,g,_)}return S}async*upload(g,_){const S=await this.getUploader(g,_);for(;!S.isComplete;)await S.uploadChunk(),yield S;return S}}return _c.default=c,_c}var lv={},QJ=Oe&&Oe.__createBinding||(Object.create?function(e,t,r,n){n===void 0&&(n=r);var a=Object.getOwnPropertyDescriptor(t,r);(!a||("get"in a?!t.__esModule:a.writable||a.configurable))&&(a={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,a)}:function(e,t,r,n){n===void 0&&(n=r),e[n]=t[r]}),eQ=Oe&&Oe.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),tQ=Oe&&Oe.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)r!=="default"&&Object.prototype.hasOwnProperty.call(e,r)&&QJ(t,e,r);return eQ(t,e),t};Object.defineProperty(lv,"__esModule",{value:!0});const px=tQ(_t);class rQ{constructor(t,r){Pe(this,"api");Pe(this,"crypto");this.api=t,this.crypto=r}getBalance(t){return this.api.get(`wallet/${t}/balance`).then(r=>r.data)}getLastTransactionID(t){return this.api.get(`wallet/${t}/last_tx`).then(r=>r.data)}generate(){return this.crypto.generateJWK()}async jwkToAddress(t){return!t||t==="use_wallet"?this.getAddress():this.getAddress(t)}async getAddress(t){if(!t||t==="use_wallet"){try{await arweaveWallet.connect(["ACCESS_ADDRESS"])}catch{}return arweaveWallet.getActiveAddress()}else return this.ownerToAddress(t.n)}async ownerToAddress(t){return px.bufferTob64Url(await this.crypto.hash(px.b64UrlToBuffer(t)))}}lv.default=rQ;var Dl={},nQ=Oe&&Oe.__createBinding||(Object.create?function(e,t,r,n){n===void 0&&(n=r);var a=Object.getOwnPropertyDescriptor(t,r);(!a||("get"in a?!t.__esModule:a.writable||a.configurable))&&(a={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,a)}:function(e,t,r,n){n===void 0&&(n=r),e[n]=t[r]}),iQ=Oe&&Oe.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),aQ=Oe&&Oe.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)r!=="default"&&Object.prototype.hasOwnProperty.call(e,r)&&nQ(t,e,r);return iQ(t,e),t};Object.defineProperty(Dl,"__esModule",{value:!0});Dl.SiloResource=void 0;const vx=aQ(_t);class oQ{constructor(t,r,n){Pe(this,"api");Pe(this,"crypto");Pe(this,"transactions");this.api=t,this.crypto=r,this.transactions=n}async get(t){if(!t)throw new Error("No Silo URI specified");const r=await this.parseUri(t),n=await this.transactions.search("Silo-Name",r.getAccessKey());if(n.length==0)throw new Error(`No data could be found for the Silo URI: ${t}`);const a=await this.transactions.get(n[0]);if(!a)throw new Error(`No data could be found for the Silo URI: ${t}`);const i=a.get("data",{decode:!0,string:!1});return this.crypto.decrypt(i,r.getEncryptionKey())}async readTransactionData(t,r){if(!r)throw new Error("No Silo URI specified");const n=await this.parseUri(r),a=t.get("data",{decode:!0,string:!1});return this.crypto.decrypt(a,n.getEncryptionKey())}async parseUri(t){const r=t.match(/^([a-z0-9-_]+)\.([0-9]+)/i);if(!r)throw new Error("Invalid Silo name, must be a name in the format of [a-z0-9]+.[0-9]+, e.g. 'bubble.7'");const n=r[1],a=Math.pow(2,parseInt(r[2])),i=await this.hash(vx.stringToBuffer(n),a),f=vx.bufferTob64(i.slice(0,15)),l=await this.hash(i.slice(16,31),1);return new cT(t,f,l)}async hash(t,r){let n=await this.crypto.hash(t);for(let a=0;aU.data||[])}};Pe(B,"init"),Pe(B,"crypto",new f.default),Pe(B,"utils",_);let I=B;return wc.default=I,wc}var dQ=Oe&&Oe.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};const K6=dQ(dv());K6.default.init=function(e={}){return new K6.default(e)};var pQ=K6.default;const vQ=Nr(pQ);function gQ(e){return fT(e)}class yQ{constructor({privateKey:t,logger:r}){this.privateKey=t,this.logger=r,this.signer=new I7(this.privateKey)}async signDataItem({fileStreamFactory:t,fileSizeFactory:r}){this.logger.debug("Signing data item...");const[n,a]=[t(),t()],i=await GR(n,a,this.signer);this.logger.debug("Successfully signed data item...");const f=this.calculateSignedDataHeadersSize({dataSize:r()});return{dataItemStreamFactory:()=>i,dataItemSizeFactory:()=>f}}async generateSignedRequestHeaders(){const t=Na.randomBytes(16).toString("hex"),r=Te.Buffer.from(t),n=await vQ.crypto.sign(this.privateKey,r);return{"x-public-key":this.privateKey.n,"x-nonce":t,"x-signature":gQ(Te.Buffer.from(n))}}calculateSignedDataHeadersSize({dataSize:t}){return[1,1,0,512,512,2,8,8,t].reduce((g,_)=>g+=_)}}class bx extends VE{static authenticated({privateKey:t,paymentServiceConfig:r={},uploadServiceConfig:n={}}){const a=new yQ({privateKey:t,logger:this.logger}),i=new Gj({...r,signer:a,logger:this.logger}),f=new Wj({...n,signer:a,logger:this.logger});return new Vj({uploadService:f,paymentService:i})}}const G6="https://payment.ardrive.io",mQ="https://ardrive.io/tos-and-privacy/",bQ=10;function xQ(e,t){const[r,n]=Or.useState(e);return Or.useEffect(()=>{const a=setTimeout(()=>n(e),t||500);return()=>{clearTimeout(a)}},[e,t]),r}async function wQ(e,t){const n=await(await fetch(`${G6}/v1/top-up/checkout-session/${t}/usd/${e*100}?destinationAddressType=email`)).json();return console.log("data",n),n}function _Q({errorCallback:e}){var R;const[t,r]=Or.useState(""),[n,a]=Or.useState(!1),i=Or.useRef(null),[f,l]=Or.useState(bQ),c=xQ(f,500),m=A=>{l(Number(Number(A.target.value).toFixed(2)))},[g,_]=Or.useState(void 0),S=Or.useRef(void 0),[M,P]=Or.useState(void 0);Or.useEffect(()=>{bx.unauthenticated({paymentServiceConfig:{url:G6}}).getFiatRates().then(({winc:U})=>{P(U)})},[]),Or.useEffect(()=>{(async U=>{const V=bx.unauthenticated({paymentServiceConfig:{url:G6}}),{winc:j}=await V.getWincForFiat({amount:Xj(U),promoCodes:[]});return j})(c).then(U=>{_(U)}).catch(U=>{console.error(U),e(`Error getting credits for USD amount: ${U.message}`)}),S.current=c},[c,e]);const I=!!g&&!!t&&!!n&&((R=i.current)==null?void 0:R.checkValidity()),B=A=>{A.preventDefault(),I&&wQ(f,t).then(U=>{const V=U.paymentSession.url;window.location.href=V})};return Xe.jsxs("form",{className:"gift-form",children:[Xe.jsx("h1",{children:"Gift credits to a friend."}),Xe.jsxs("div",{className:"form-section",children:[Xe.jsx("label",{className:"form-label",children:"USD amount*"}),Xe.jsxs("div",{id:"usd-form-input",children:[Xe.jsx("span",{id:"dollar-sign",children:"$"}),Xe.jsx("input",{type:"number",id:"usd-input",value:f,onChange:m,required:!0})]})]}),g&&Xe.jsx("div",{children:M&&Xe.jsxs("div",{id:"conversions",children:["$",Xe.jsx("span",{className:"conversion-amount",children:S.current})," ","≈"," ",Xe.jsx("span",{className:"conversion-amount",children:(Number(g)/1e12).toFixed(4)}),"credits ≈"," ",Xe.jsx("span",{className:"conversion-amount",children:(Number(g)/Number(M)).toFixed(2)}),"GiB"]})}),Xe.jsxs("div",{className:"form-section",children:[Xe.jsx("label",{className:"form-label",children:"Recipient email address*"}),Xe.jsx("input",{type:"email",className:"form-input",id:"recipient-email",placeholder:"Enter the recipient's email address here",value:t,ref:i,required:!0,onChange:A=>{r(A.target.value)}})]}),Xe.jsxs("div",{className:"form-section",children:[Xe.jsx("label",{className:"form-label",children:"Gift message (optional up to 250 characters)"}),Xe.jsx("textarea",{className:"form-input",id:"giftMessage",rows:3,placeholder:"Enter a message to the recipient of the Turbo Credits here",maxLength:250,required:!1})]}),Xe.jsxs("div",{className:"terms-and-conditions",children:[Xe.jsx("input",{type:"checkbox",id:"terms-and-conditions-checkbox",name:"terms-and-conditions-checkbox",value:"terms-and-conditions-checkbox",required:!0,onChange:A=>{a(A.target.checked)}}),Xe.jsxs("span",{children:["I Agree to the",Xe.jsx("a",{href:mQ,children:"Terms of Service and Privacy Policy"}),"."]})]}),Xe.jsx("button",{type:"submit",id:"gift-form-submit-button",onClick:A=>B(A),disabled:!I,children:"Proceed to Checkout"})]})}function SQ(){const[e,t]=Or.useState(void 0);return Xe.jsxs(Xe.Fragment,{children:[Xe.jsx($O,{}),e&&Xe.jsx("div",{className:"alert alert-danger",role:"alert",children:e}),Xe.jsx(_Q,{errorCallback:t})]})}Bp.createRoot(document.getElementById("root")).render(Xe.jsx(kT.StrictMode,{children:Xe.jsx(SQ,{})}))});export default EQ(); +${JSON.stringify(Te.Buffer.from(J))},${JSON.stringify(Te.Buffer.from(te))},${G} => ${JSON.stringify(d)}`;return j(E,o)}e.debug=j}(Ip)),Ip}var cx;function uv(){if(cx)return $f;cx=1;var e=Oe&&Oe.__createBinding||(Object.create?function(g,_,S,M){M===void 0&&(M=S);var P=Object.getOwnPropertyDescriptor(_,S);(!P||("get"in P?!_.__esModule:P.writable||P.configurable))&&(P={enumerable:!0,get:function(){return _[S]}}),Object.defineProperty(g,M,P)}:function(g,_,S,M){M===void 0&&(M=S),g[M]=_[S]}),t=Oe&&Oe.__setModuleDefault||(Object.create?function(g,_){Object.defineProperty(g,"default",{enumerable:!0,value:_})}:function(g,_){g.default=_}),r=Oe&&Oe.__importStar||function(g){if(g&&g.__esModule)return g;var _={};if(g!=null)for(var S in g)S!=="default"&&Object.prototype.hasOwnProperty.call(g,S)&&e(_,g,S);return t(_,g),_},n=Oe&&Oe.__importDefault||function(g){return g&&g.__esModule?g:{default:g}};Object.defineProperty($f,"__esModule",{value:!0}),$f.Tag=void 0;const a=r(_t),i=n(XJ()),f=lT();class l{get(_,S){if(!Object.getOwnPropertyNames(this).includes(_))throw new Error(`Field "${_}" is not a property of the Arweave Transaction class.`);if(this[_]instanceof Uint8Array)return S&&S.decode&&S.string?a.bufferToString(this[_]):S&&S.decode&&!S.string?this[_]:a.bufferTob64Url(this[_]);if(this[_]instanceof Array){if((S==null?void 0:S.decode)!==void 0||(S==null?void 0:S.string)!==void 0)throw _==="tags"&&console.warn(`Did you mean to use 'transaction["tags"]' ?`),new Error("Cannot decode or stringify an array.");return this[_]}return S&&S.decode==!0?S&&S.string?a.b64UrlToString(this[_]):a.b64UrlToBuffer(this[_]):this[_]}}class c extends l{constructor(S,M,P=!1){super();Pe(this,"name");Pe(this,"value");this.name=S,this.value=M}}$f.Tag=c;class m extends l{constructor(S={}){super();Pe(this,"format",2);Pe(this,"id","");Pe(this,"last_tx","");Pe(this,"owner","");Pe(this,"tags",[]);Pe(this,"target","");Pe(this,"quantity","0");Pe(this,"data_size","0");Pe(this,"data",new Uint8Array);Pe(this,"data_root","");Pe(this,"reward","0");Pe(this,"signature","");Pe(this,"chunks");Object.assign(this,S),typeof this.data=="string"&&(this.data=a.b64UrlToBuffer(this.data)),S.tags&&(this.tags=S.tags.map(M=>new c(M.name,M.value)))}addTag(S,M){this.tags.push(new c(a.stringToB64Url(S),a.stringToB64Url(M)))}toJSON(){return{format:this.format,id:this.id,last_tx:this.last_tx,owner:this.owner,tags:this.tags,target:this.target,quantity:this.quantity,data:a.bufferTob64Url(this.data),data_size:this.data_size,data_root:this.data_root,data_tree:this.data_tree,reward:this.reward,signature:this.signature}}setOwner(S){this.owner=S}setSignature({id:S,owner:M,reward:P,tags:I,signature:B}){this.id=S,this.owner=M,P&&(this.reward=P),I&&(this.tags=I),this.signature=B}async prepareChunks(S){!this.chunks&&S.byteLength>0&&(this.chunks=await(0,f.generateTransactionChunks)(S),this.data_root=a.bufferTob64Url(this.chunks.data_root)),!this.chunks&&S.byteLength===0&&(this.chunks={chunks:[],data_root:new Uint8Array,proofs:[]},this.data_root="")}getChunk(S,M){if(!this.chunks)throw new Error("Chunks have not been prepared");const P=this.chunks.proofs[S],I=this.chunks.chunks[S];return{data_root:this.data_root,data_size:this.data_size,data_path:a.bufferTob64Url(P.proof),offset:P.offset.toString(),chunk:a.bufferTob64Url(M.slice(I.minByteRange,I.maxByteRange))}}async getSignatureData(){switch(this.format){case 1:let S=this.tags.reduce((P,I)=>a.concatBuffers([P,I.get("name",{decode:!0,string:!1}),I.get("value",{decode:!0,string:!1})]),new Uint8Array);return a.concatBuffers([this.get("owner",{decode:!0,string:!1}),this.get("target",{decode:!0,string:!1}),this.get("data",{decode:!0,string:!1}),a.stringToBuffer(this.quantity),a.stringToBuffer(this.reward),this.get("last_tx",{decode:!0,string:!1}),S]);case 2:this.data_root||await this.prepareChunks(this.data);const M=this.tags.map(P=>[P.get("name",{decode:!0,string:!1}),P.get("value",{decode:!0,string:!1})]);return await(0,i.default)([a.stringToBuffer(this.format.toString()),this.get("owner",{decode:!0,string:!1}),this.get("target",{decode:!0,string:!1}),a.stringToBuffer(this.quantity),a.stringToBuffer(this.reward),this.get("last_tx",{decode:!0,string:!1}),M,a.stringToBuffer(this.data_size),this.get("data_root",{decode:!0,string:!1})]);default:throw new Error(`Unexpected transaction format: ${this.format}`)}}}return $f.default=m,$f}var z0={},hx;function YJ(){if(hx)return z0;hx=1;var e=Oe&&Oe.__createBinding||(Object.create?function(S,M,P,I){I===void 0&&(I=P);var B=Object.getOwnPropertyDescriptor(M,P);(!B||("get"in B?!M.__esModule:B.writable||B.configurable))&&(B={enumerable:!0,get:function(){return M[P]}}),Object.defineProperty(S,I,B)}:function(S,M,P,I){I===void 0&&(I=P),S[I]=M[P]}),t=Oe&&Oe.__setModuleDefault||(Object.create?function(S,M){Object.defineProperty(S,"default",{enumerable:!0,value:M})}:function(S,M){S.default=M}),r=Oe&&Oe.__importStar||function(S){if(S&&S.__esModule)return S;var M={};if(S!=null)for(var P in S)P!=="default"&&Object.prototype.hasOwnProperty.call(S,P)&&e(M,S,P);return t(M,S),M},n=Oe&&Oe.__importDefault||function(S){return S&&S.__esModule?S:{default:S}};Object.defineProperty(z0,"__esModule",{value:!0}),z0.TransactionUploader=void 0;const a=n(uv()),i=r(_t),f=qo,l=lT(),c=1,m=["invalid_json","chunk_too_big","data_path_too_big","offset_too_big","data_size_too_big","chunk_proof_ratio_not_attractive","invalid_proof"],g=1e3*40;class _{constructor(M,P){Pe(this,"api");Pe(this,"chunkIndex",0);Pe(this,"txPosted",!1);Pe(this,"transaction");Pe(this,"lastRequestTimeEnd",0);Pe(this,"totalErrors",0);Pe(this,"data");Pe(this,"lastResponseStatus",0);Pe(this,"lastResponseError","");if(this.api=M,!P.id)throw new Error("Transaction is not signed");if(!P.chunks)throw new Error("Transaction chunks not prepared");this.data=P.data,this.transaction=new a.default(Object.assign({},P,{data:new Uint8Array(0)}))}get isComplete(){return this.txPosted&&this.chunkIndex===this.transaction.chunks.chunks.length}get totalChunks(){return this.transaction.chunks.chunks.length}get uploadedChunks(){return this.chunkIndex}get pctComplete(){return Math.trunc(this.uploadedChunks/this.totalChunks*100)}async uploadChunk(M){if(this.isComplete)throw new Error("Upload is already complete");if(this.lastResponseError!==""?this.totalErrors++:this.totalErrors=0,this.totalErrors===100)throw new Error(`Unable to complete upload: ${this.lastResponseStatus}: ${this.lastResponseError}`);let P=this.lastResponseError===""?0:Math.max(this.lastRequestTimeEnd+g-Date.now(),g);if(P>0&&(P=P-P*Math.random()*.3,await new Promise(A=>setTimeout(A,P))),this.lastResponseError="",!this.txPosted){await this.postTransaction();return}M&&(this.chunkIndex=M);const I=this.transaction.getChunk(M||this.chunkIndex,this.data);if(!await(0,l.validatePath)(this.transaction.chunks.data_root,parseInt(I.offset),0,parseInt(I.data_size),i.b64UrlToBuffer(I.data_path)))throw new Error(`Unable to validate chunk ${this.chunkIndex}`);const R=await this.api.post("chunk",this.transaction.getChunk(this.chunkIndex,this.data)).catch(A=>(console.error(A.message),{status:-1,data:{error:A.message}}));if(this.lastRequestTimeEnd=Date.now(),this.lastResponseStatus=R.status,this.lastResponseStatus==200)this.chunkIndex++;else if(this.lastResponseError=(0,f.getError)(R),m.includes(this.lastResponseError))throw new Error(`Fatal error uploading chunk ${this.chunkIndex}: ${this.lastResponseError}`)}static async fromSerialized(M,P,I){if(!P||typeof P.chunkIndex!="number"||typeof P.transaction!="object")throw new Error("Serialized object does not match expected format.");var B=new a.default(P.transaction);B.chunks||await B.prepareChunks(I);const R=new _(M,B);if(R.chunkIndex=P.chunkIndex,R.lastRequestTimeEnd=P.lastRequestTimeEnd,R.lastResponseError=P.lastResponseError,R.lastResponseStatus=P.lastResponseStatus,R.txPosted=P.txPosted,R.data=I,R.transaction.data_root!==P.transaction.data_root)throw new Error("Data mismatch: Uploader doesn't match provided data.");return R}static async fromTransactionId(M,P){const I=await M.get(`tx/${P}`);if(I.status!==200)throw new Error(`Tx ${P} not found: ${I.status}`);const B=I.data;return B.data=new Uint8Array(0),{txPosted:!0,chunkIndex:0,lastResponseError:"",lastRequestTimeEnd:0,lastResponseStatus:0,transaction:B}}toJSON(){return{chunkIndex:this.chunkIndex,transaction:this.transaction,lastRequestTimeEnd:this.lastRequestTimeEnd,lastResponseStatus:this.lastResponseStatus,lastResponseError:this.lastResponseError,txPosted:this.txPosted}}async postTransaction(){if(this.totalChunks<=c){this.transaction.data=this.data;const I=await this.api.post("tx",this.transaction).catch(B=>(console.error(B),{status:-1,data:{error:B.message}}));if(this.lastRequestTimeEnd=Date.now(),this.lastResponseStatus=I.status,this.transaction.data=new Uint8Array(0),I.status>=200&&I.status<300){this.txPosted=!0,this.chunkIndex=c;return}throw this.lastResponseError=(0,f.getError)(I),new Error(`Unable to upload transaction: ${I.status}, ${this.lastResponseError}`)}const P=await this.api.post("tx",this.transaction);if(this.lastRequestTimeEnd=Date.now(),this.lastResponseStatus=P.status,!(P.status>=200&&P.status<300))throw this.lastResponseError=(0,f.getError)(P),new Error(`Unable to upload transaction: ${P.status}, ${this.lastResponseError}`);this.txPosted=!0}}return z0.TransactionUploader=_,z0}var dx;function JJ(){if(dx)return _c;dx=1;var e=Oe&&Oe.__createBinding||(Object.create?function(m,g,_,S){S===void 0&&(S=_);var M=Object.getOwnPropertyDescriptor(g,_);(!M||("get"in M?!g.__esModule:M.writable||M.configurable))&&(M={enumerable:!0,get:function(){return g[_]}}),Object.defineProperty(m,S,M)}:function(m,g,_,S){S===void 0&&(S=_),m[S]=g[_]}),t=Oe&&Oe.__setModuleDefault||(Object.create?function(m,g){Object.defineProperty(m,"default",{enumerable:!0,value:g})}:function(m,g){m.default=g}),r=Oe&&Oe.__importStar||function(m){if(m&&m.__esModule)return m;var g={};if(m!=null)for(var _ in m)_!=="default"&&Object.prototype.hasOwnProperty.call(m,_)&&e(g,m,_);return t(g,m),g},n=Oe&&Oe.__importDefault||function(m){return m&&m.__esModule?m:{default:m}};Object.defineProperty(_c,"__esModule",{value:!0});const a=n(qo),i=n(uv()),f=r(_t),l=YJ();class c{constructor(g,_,S){Pe(this,"api");Pe(this,"crypto");Pe(this,"chunks");this.api=g,this.crypto=_,this.chunks=S}async getTransactionAnchor(){const g=await this.api.get("tx_anchor");if(!g.data.match(/^[a-z0-9_-]{43,}/i)||!g.ok)throw new Error(`Could not getTransactionAnchor. Received: ${g.data}. Status: ${g.status}, ${g.statusText}`);return g.data}async getPrice(g,_){let S=_?`price/${g}/${_}`:`price/${g}`;const M=await this.api.get(S);if(!/^\d+$/.test(M.data)||!M.ok)throw new Error(`Could not getPrice. Received: ${M.data}. Status: ${M.status}, ${M.statusText}`);return M.data}async get(g){const _=await this.api.get(`tx/${g}`);if(_.status==200){const S=parseInt(_.data.data_size);if(_.data.format>=2&&S>0&&S<=1024*1024*12){const M=await this.getData(g);return new i.default({..._.data,data:M})}return new i.default({..._.data,format:_.data.format||1})}throw _.status==404?new a.default("TX_NOT_FOUND"):_.status==410?new a.default("TX_FAILED"):new a.default("TX_INVALID")}fromRaw(g){return new i.default(g)}async search(g,_){return this.api.post("arql",{op:"equals",expr1:g,expr2:_}).then(S=>S.data?S.data:[])}getStatus(g){return this.api.get(`tx/${g}/status`).then(_=>_.status==200?{status:200,confirmed:_.data}:{status:_.status,confirmed:null})}async getData(g,_){let S;try{S=await this.chunks.downloadChunkedData(g)}catch(M){console.error(`Error while trying to download chunked data for ${g}`),console.error(M)}if(!S){console.warn(`Falling back to gateway cache for ${g}`);try{const{data:M,ok:P,status:I,statusText:B}=await this.api.get(`/${g}`,{responseType:"arraybuffer"});if(!P)throw new Error("Bad http status code",{cause:{status:I,statusText:B}});S=M}catch(M){console.error(`Error while trying to download contiguous data from gateway cache for ${g}`),console.error(M)}}if(!S)throw new Error(`${g} data was not found!`);return _&&_.decode&&!_.string?S:_&&_.decode&&_.string?f.bufferToString(S):f.bufferTob64Url(S)}async sign(g,_,S){const P=typeof _=="object"&&(B=>{let R=!0;return["n","e","d","p","q","dp","dq","qi"].map(A=>!(A in B)&&(R=!1)),R})(_),I=typeof arweaveWallet=="object";if(!P&&!I)throw new Error("No valid JWK or external wallet found to sign transaction.");if(P){g.setOwner(_.n);let B=await g.getSignatureData(),R=await this.crypto.sign(_,B,S),A=await this.crypto.hash(R);g.setSignature({id:f.bufferTob64Url(A),owner:_.n,signature:f.bufferTob64Url(R)})}else if(I){try{(await arweaveWallet.getPermissions()).includes("SIGN_TRANSACTION")||await arweaveWallet.connect(["SIGN_TRANSACTION"])}catch{}const B=await arweaveWallet.sign(g,S);g.setSignature({id:B.id,owner:B.owner,reward:B.reward,tags:B.tags,signature:B.signature})}else throw new Error("An error occurred while signing. Check wallet is valid")}async verify(g){const _=await g.getSignatureData(),S=g.get("signature",{decode:!0,string:!1}),M=f.bufferTob64Url(await this.crypto.hash(S));if(g.id!==M)throw new Error("Invalid transaction signature or ID! The transaction ID doesn't match the expected SHA-256 hash of the signature.");return this.crypto.verify(g.owner,_,S)}async post(g){if(typeof g=="string"?g=new i.default(JSON.parse(g)):typeof g.readInt32BE=="function"?g=new i.default(JSON.parse(g.toString())):typeof g=="object"&&!(g instanceof i.default)&&(g=new i.default(g)),!(g instanceof i.default))throw new Error("Must be Transaction object");g.chunks||await g.prepareChunks(g.data);const _=await this.getUploader(g,g.data);try{for(;!_.isComplete;)await _.uploadChunk()}catch(S){if(_.lastResponseStatus>0)return{status:_.lastResponseStatus,statusText:_.lastResponseError,data:{error:_.lastResponseError}};throw S}return{status:200,statusText:"OK",data:{}}}async getUploader(g,_){let S;if(_ instanceof ArrayBuffer&&(_=new Uint8Array(_)),g instanceof i.default){if(_||(_=g.data),!(_ instanceof Uint8Array))throw new Error("Data format is invalid");g.chunks||await g.prepareChunks(_),S=new l.TransactionUploader(this.api,g),(!S.data||S.data.length===0)&&(S.data=_)}else{if(typeof g=="string"&&(g=await l.TransactionUploader.fromTransactionId(this.api,g)),!_||!(_ instanceof Uint8Array))throw new Error("Must provide data when resuming upload");S=await l.TransactionUploader.fromSerialized(this.api,g,_)}return S}async*upload(g,_){const S=await this.getUploader(g,_);for(;!S.isComplete;)await S.uploadChunk(),yield S;return S}}return _c.default=c,_c}var lv={},QJ=Oe&&Oe.__createBinding||(Object.create?function(e,t,r,n){n===void 0&&(n=r);var a=Object.getOwnPropertyDescriptor(t,r);(!a||("get"in a?!t.__esModule:a.writable||a.configurable))&&(a={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,a)}:function(e,t,r,n){n===void 0&&(n=r),e[n]=t[r]}),eQ=Oe&&Oe.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),tQ=Oe&&Oe.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)r!=="default"&&Object.prototype.hasOwnProperty.call(e,r)&&QJ(t,e,r);return eQ(t,e),t};Object.defineProperty(lv,"__esModule",{value:!0});const px=tQ(_t);class rQ{constructor(t,r){Pe(this,"api");Pe(this,"crypto");this.api=t,this.crypto=r}getBalance(t){return this.api.get(`wallet/${t}/balance`).then(r=>r.data)}getLastTransactionID(t){return this.api.get(`wallet/${t}/last_tx`).then(r=>r.data)}generate(){return this.crypto.generateJWK()}async jwkToAddress(t){return!t||t==="use_wallet"?this.getAddress():this.getAddress(t)}async getAddress(t){if(!t||t==="use_wallet"){try{await arweaveWallet.connect(["ACCESS_ADDRESS"])}catch{}return arweaveWallet.getActiveAddress()}else return this.ownerToAddress(t.n)}async ownerToAddress(t){return px.bufferTob64Url(await this.crypto.hash(px.b64UrlToBuffer(t)))}}lv.default=rQ;var Dl={},nQ=Oe&&Oe.__createBinding||(Object.create?function(e,t,r,n){n===void 0&&(n=r);var a=Object.getOwnPropertyDescriptor(t,r);(!a||("get"in a?!t.__esModule:a.writable||a.configurable))&&(a={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,a)}:function(e,t,r,n){n===void 0&&(n=r),e[n]=t[r]}),iQ=Oe&&Oe.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),aQ=Oe&&Oe.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)r!=="default"&&Object.prototype.hasOwnProperty.call(e,r)&&nQ(t,e,r);return iQ(t,e),t};Object.defineProperty(Dl,"__esModule",{value:!0});Dl.SiloResource=void 0;const vx=aQ(_t);class oQ{constructor(t,r,n){Pe(this,"api");Pe(this,"crypto");Pe(this,"transactions");this.api=t,this.crypto=r,this.transactions=n}async get(t){if(!t)throw new Error("No Silo URI specified");const r=await this.parseUri(t),n=await this.transactions.search("Silo-Name",r.getAccessKey());if(n.length==0)throw new Error(`No data could be found for the Silo URI: ${t}`);const a=await this.transactions.get(n[0]);if(!a)throw new Error(`No data could be found for the Silo URI: ${t}`);const i=a.get("data",{decode:!0,string:!1});return this.crypto.decrypt(i,r.getEncryptionKey())}async readTransactionData(t,r){if(!r)throw new Error("No Silo URI specified");const n=await this.parseUri(r),a=t.get("data",{decode:!0,string:!1});return this.crypto.decrypt(a,n.getEncryptionKey())}async parseUri(t){const r=t.match(/^([a-z0-9-_]+)\.([0-9]+)/i);if(!r)throw new Error("Invalid Silo name, must be a name in the format of [a-z0-9]+.[0-9]+, e.g. 'bubble.7'");const n=r[1],a=Math.pow(2,parseInt(r[2])),i=await this.hash(vx.stringToBuffer(n),a),f=vx.bufferTob64(i.slice(0,15)),l=await this.hash(i.slice(16,31),1);return new cT(t,f,l)}async hash(t,r){let n=await this.crypto.hash(t);for(let a=0;aU.data||[])}};Pe(B,"init"),Pe(B,"crypto",new f.default),Pe(B,"utils",_);let I=B;return wc.default=I,wc}var dQ=Oe&&Oe.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};const K6=dQ(dv());K6.default.init=function(e={}){return new K6.default(e)};var pQ=K6.default;const vQ=Nr(pQ);function gQ(e){return fT(e)}class yQ{constructor({privateKey:t,logger:r}){this.privateKey=t,this.logger=r,this.signer=new I7(this.privateKey)}async signDataItem({fileStreamFactory:t,fileSizeFactory:r}){this.logger.debug("Signing data item...");const[n,a]=[t(),t()],i=await GR(n,a,this.signer);this.logger.debug("Successfully signed data item...");const f=this.calculateSignedDataHeadersSize({dataSize:r()});return{dataItemStreamFactory:()=>i,dataItemSizeFactory:()=>f}}async generateSignedRequestHeaders(){const t=Na.randomBytes(16).toString("hex"),r=Te.Buffer.from(t),n=await vQ.crypto.sign(this.privateKey,r);return{"x-public-key":this.privateKey.n,"x-nonce":t,"x-signature":gQ(Te.Buffer.from(n))}}calculateSignedDataHeadersSize({dataSize:t}){return[1,1,0,512,512,2,8,8,t].reduce((g,_)=>g+=_)}}class bx extends VE{static authenticated({privateKey:t,paymentServiceConfig:r={},uploadServiceConfig:n={}}){const a=new yQ({privateKey:t,logger:this.logger}),i=new Gj({...r,signer:a,logger:this.logger}),f=new Wj({...n,signer:a,logger:this.logger});return new Vj({uploadService:f,paymentService:i})}}const G6="https://payment.ardrive.io",mQ="https://ardrive.io/tos-and-privacy/",bQ=10;function xQ(e,t){const[r,n]=Or.useState(e);return Or.useEffect(()=>{const a=setTimeout(()=>n(e),t||500);return()=>{clearTimeout(a)}},[e,t]),r}async function wQ(e,t){const n=await(await fetch(`${G6}/v1/top-up/checkout-session/${t}/usd/${e*100}?destinationAddressType=email`)).json();return console.log("data",n),n}function _Q({errorCallback:e}){var R;const[t,r]=Or.useState(""),[n,a]=Or.useState(!1),i=Or.useRef(null),[f,l]=Or.useState(bQ),c=xQ(f,500),m=A=>{l(Number(Number(A.target.value).toFixed(2)))},[g,_]=Or.useState(void 0),S=Or.useRef(void 0),[M,P]=Or.useState(void 0);Or.useEffect(()=>{bx.unauthenticated({paymentServiceConfig:{url:G6}}).getFiatRates().then(({winc:U})=>{P(U)})},[]),Or.useEffect(()=>{(async U=>{const V=bx.unauthenticated({paymentServiceConfig:{url:G6}}),{winc:j}=await V.getWincForFiat({amount:Xj(U),promoCodes:[]});return j})(c).then(U=>{_(U)}).catch(U=>{console.error(U),e(`Error getting credits for USD amount: ${U.message}`)}),S.current=c},[c,e]);const I=!!g&&!!t&&!!n&&((R=i.current)==null?void 0:R.checkValidity()),B=A=>{A.preventDefault(),I&&wQ(f,t).then(U=>{const V=U.paymentSession.url;window.location.href=V})};return Xe.jsxs("form",{className:"gift-form",children:[Xe.jsx("h1",{children:"Gift Credits to a friend."}),Xe.jsxs("div",{className:"form-section",children:[Xe.jsx("label",{className:"form-label",children:"USD amount*"}),Xe.jsxs("div",{id:"usd-form-input",children:[Xe.jsx("span",{id:"dollar-sign",children:"$"}),Xe.jsx("input",{type:"number",id:"usd-input",value:f,onChange:m,required:!0})]})]}),g&&Xe.jsx("div",{children:M&&Xe.jsxs("div",{id:"conversions",children:["$",Xe.jsx("span",{className:"conversion-amount",children:S.current})," ","≈"," ",Xe.jsx("span",{className:"conversion-amount",children:(Number(g)/1e12).toFixed(4)}),"Credits ≈"," ",Xe.jsx("span",{className:"conversion-amount",children:(Number(g)/Number(M)).toFixed(2)}),"GiB"]})}),Xe.jsxs("div",{className:"form-section",children:[Xe.jsx("label",{className:"form-label",children:"Recipient email address*"}),Xe.jsx("input",{type:"email",className:"form-input",id:"recipient-email",placeholder:"Enter the recipient's email address here",value:t,ref:i,required:!0,onChange:A=>{r(A.target.value)}})]}),Xe.jsxs("div",{className:"form-section",children:[Xe.jsx("label",{className:"form-label",children:"Gift message (optional up to 250 characters)"}),Xe.jsx("textarea",{className:"form-input",id:"gift-message",placeholder:"Enter a message to the recipient of the Turbo Credits here",maxLength:250,required:!1})]}),Xe.jsxs("div",{className:"terms-and-conditions",children:[Xe.jsx("input",{type:"checkbox",id:"terms-and-conditions-checkbox",name:"terms-and-conditions-checkbox",value:"terms-and-conditions-checkbox",required:!0,onChange:A=>{a(A.target.checked)}}),Xe.jsxs("span",{children:["I Agree to the",Xe.jsx("a",{href:mQ,children:"Terms of Service and Privacy Policy"}),"."]})]}),Xe.jsx("button",{type:"submit",id:"gift-form-submit-button",onClick:A=>B(A),disabled:!I,children:"Proceed to Checkout"})]})}function SQ(){const[e,t]=Or.useState(void 0);return Xe.jsxs(Xe.Fragment,{children:[Xe.jsx($O,{}),e&&Xe.jsx("div",{className:"alert alert-danger",role:"alert",children:e}),Xe.jsx(_Q,{errorCallback:t})]})}Bp.createRoot(document.getElementById("root")).render(Xe.jsx(kT.StrictMode,{children:Xe.jsx(SQ,{})}))});export default EQ(); diff --git a/index.html b/index.html index b5f752f..23d07a3 100644 --- a/index.html +++ b/index.html @@ -35,8 +35,8 @@ crossorigin /> ArDrive Turbo App - - + +