UNPKG

sandstone-proxy

Version:

An experimental web proxy utilizing sandboxed iframes and no service worker.

1 lines 21.8 kB
var sandstone_frame;(()=>{"use strict";var e={d:(t,r)=>{for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{context:()=>n,loader:()=>o,network:()=>s,rpc:()=>r});var r={};e.r(r),e.d(r,{call_procedure:()=>h,create_rpc_wrapper:()=>p,message_listener:()=>u,parent:()=>c,role:()=>i,rpc_handlers:()=>a,rpc_requests:()=>l,set_parent:()=>f,set_role:()=>d});var n={};e.r(n),e.d(n,{convert_url:()=>I,ctx:()=>x,intercept_property:()=>q,is_worker:()=>M,proxy_function:()=>A,run_script:()=>H,run_script_safe:()=>D,safe_script_template:()=>U,update_ctx:()=>k,wrap_function:()=>P,wrap_obj:()=>N});var s={};e.r(s),e.d(s,{WebSocket:()=>Q,cache_put:()=>J,create_blob_url:()=>z,enable_network:()=>X,fetch:()=>K,known_urls:()=>G,requests_allowed:()=>V,resource_cache:()=>F,rpc_fetch:()=>j,rpc_ws_close:()=>W,rpc_ws_event:()=>B,rpc_ws_new:()=>C,rpc_ws_send:()=>$});var o={};e.r(o),e.d(o,{frame_id:()=>ue,is_loaded:()=>he,local_storage:()=>ae,navigate:()=>ie,runtime_src:()=>le,set_frame_id:()=>pe,set_url:()=>de,url:()=>ce});let i=null;const a={},l={};let c=self.parent?self.parent:self;async function u(e){let t=e.data,r=e.source||e.currentTarget;if(void 0!==t.type)if(console.log(`RPC ${i} got`,t),"procedure"===t.type){let e=await async function(e){if(!a[e.procedure])return;let t;try{t={value:await a[e.procedure](...e.arguments),success:!0}}catch(e){console.error(e),t={value:e,success:!1}}return{type:"reply",id:e.id,content:t}}(t);if(!r)return;e&&r.postMessage(e,{targetOrigin:"*"})}else if("reply"===t.type)!function(e){l[e.id]&&(l[e.id](e.content),delete l[e.id])}(t);else if("attach"===t.type){let r=e.ports[0];"frame"===i?c.postMessage(t,{targetOrigin:"*",transfer:[r]}):r.onmessage=u}}async function h(e,t,r){globalThis.HTMLIFrameElement&&e instanceof globalThis.HTMLIFrameElement&&(e=e.contentWindow||e);let n={type:"procedure",id:Math.random()+"",procedure:t,arguments:r};return await new Promise(((t,r)=>{l[n.id]=e=>{e.success?t(e.value):r(e.value)},console.log(`RPC ${i} sending`,n),e.postMessage(n,{targetOrigin:"*"})}))}function p(e,t){return function(){return h("parent"===e?c:e,t,[...arguments])}}function d(e){i=e}function f(e){let t={type:"attach",id:Math.random()+""};c.postMessage(t,{targetOrigin:"*",transfer:[e.port1]}),c.removeEventListener("message",u),c=e.port2,c.addEventListener("message",u),c.start()}async function _(e){let t=Array(e.length);for(let[r,n]of e.entries())try{t[r]=await n}catch(e){console.error(e)}return t}self.addEventListener("message",u);let g=null;class m{constructor(){g=new URL(ce);for(let e in g)"function"!=typeof e&&Object.defineProperty(this,e,{get:()=>g[e],set:t=>{"href"!==e?(g[e]=t,this.assign(g.href)):this.assign(t)}})}assign(e){g=new URL(e,g),ie(ue,g.href)}replace(e){this.assign(e)}reload(){this.assign(this.href)}}class y extends URL{constructor(e,t){e=e instanceof URL?e.href:e,t=t instanceof URL?t.href:t,super(e=G[e]||e,t=G[t]||t)}}class w{#e;#t;scrollRestoration="auto";get length(){return 1}get state(){return this.#e}back(){}forward(){}go(){}pushState(e,t,r){this.#e=e,this.#t=r;let n=I(r,x.location.href);g.href=n,ie(ue,n,!1)}replaceState(e,t,r){this.pushState(e,t,r)}}class b{#r;#n;#s;constructor(e){return this.#r=new Map,this.#n=e,this.#s=!1,new Proxy(this,{get:(e,t,r)=>"function"==typeof this[t]?this[t].bind(this):this.#r.has(t)?this.#r.get(t):this[t],set:(e,t,r)=>{this.setItem(t,r)}})}#o(){this.#s||(this.#s=!0,setTimeout((()=>{let e=[...this.#r];"local"===this.#n&&ae(ue,e),this.#s=!1}),100))}clear(){this.#r.clear(),this.#o()}getItem(e){return this.#r.get(e+"")}setItem(e,t){this.#r.set(e+"",t+""),this.#o()}removeItem(e){this.#r.delete(e+""),this.#o()}_get_entries(){return[...this.#r]}toString(){return"[object Storage]"}}function v(...e){let t=e.map((e=>I(e,ce)));if(console.log("DEBUG importScripts",V,t),V)for(let e of t)if("string"==typeof F[e])H(F[e]);else{if(!1===F[e])throw Error("Script network request failed");console.warn("WARN importScripts cache miss for",e),K(e).then((e=>e.text())).then(H)}else self.postMessage({frame_id:ue,urls:t})}class E extends EventTarget{#t;#i;#a;#l;#c;constructor(e,t){console.log("DEBUG new Worker",e,t),super(),this.#t=e,this.#i=t,this.#a=null,this.#l=[],this.#c=!1,this.onerror=()=>{},this.onmessage=()=>{},this.onmessageerror=()=>{},this.#u()}async#u(){let e=await K(this.#t),t=JSON.stringify(await e.text()),r=""+Math.random(),n=new Blob([`\n ${le}\n sandstone_frame.loader.set_url("${ce}");\n sandstone_frame.loader.set_frame_id("${r}");\n sandstone_frame.rpc.set_parent(new MessageChannel());\n sandstone_frame.context.update_ctx();\n sandstone_frame.context.run_script(${t});\n `],{type:"text/javascript"}),s=URL.createObjectURL(n);if(this.#c)return;let o,i=new Worker(s,this.#i),a=new Set;i.onmessage=e=>{if(e.data.frame_id===r)for(let t of e.data.urls)a.add(t)},i.onerror=()=>{o()},await new Promise((e=>{o=e,setTimeout(e,500)})),i.terminate();let l=[],c={};for(let e of a)c[e]=!1,l.push((async()=>{let t=await K(e),r=await t.text();c[e]=r})());await _(l),console.log("DEBUG recorded urls",a);let h=[];for(let e of a){let t=JSON.stringify(e),r=JSON.stringify(c[e]);h.push(`sandstone_frame.network.cache_put(${t}, ${r});`)}let p=h.join("\n"),d=`\n ${le}\n ${p}\n sandstone_frame.loader.set_url(${JSON.stringify(ce)});\n sandstone_frame.loader.set_frame_id("${r}");\n sandstone_frame.rpc.set_parent(new MessageChannel());\n sandstone_frame.network.enable_network();\n sandstone_frame.context.update_ctx();\n sandstone_frame.context.run_script(${t});\n `,f=z(new Blob([d],{type:"text/javascript"}),this.#t);this.#a=new Worker(f,this.#i);for(let e of["error","message","messageerror"])this.#h(e);this.#a.addEventListener("message",(e=>{u(e),e.stopImmediatePropagation()}),{once:!0}),window.addEventListener("beforeunload",(()=>{this.terminate()}),null,!0)}#h(e){this.#a.addEventListener(e,(t=>{this["on"+e](t);let r=new t.constructor(e);N(t,r),this.dispatchEvent(r)}))}postMessage(e,t){null==this.#a?this.#l.push([e,t]):this.#a.postMessage(e,t)}terminate(){this.#a.terminate(),this.#c=!0}}class T extends EventTarget{UNSENT=0;OPENED=1;HEADERS_RECEIVED=2;LOADING=3;DONE=4;#p;#d;#f;#_;#g;#m;#y;#w;constructor(){super(),console.log("DEBUG XHR.constructor",this),this.#b(),this.#_=null,this.timeout=0,this.responseType="",this.withCredentials=!1,this.#v(["abort","error","load","loadend","loadstart","progress","readystatechange","timeout"],this),this.#v(["abort","error","load","loadend","loadstart","progress","timeout"],this.upload)}#v(e,t){for(let r of e)t["on"+r]=null}#b(){this.#p=0,this.#d=null,this.#f=null,this.#m=null,this.#y={},this.#w=!1,this.#g=new EventTarget}#E(e,t){if(!t)return this.#E(e,this),void this.#E(e,this.#g);t.dispatchEvent(e),"function"==typeof t["on"+e.type]&&t["on"+e.type](e)}abort(){this.#w=!0,this.readyState=this.UNSENT,this.#d=null,this.#E(new Event("abort")),this.#E(new Event("abort"),this.#g)}getAllResponseHeaders(){if(!this.#d)return"";let e="";for(let[t,r]of this.#d.headers)e+=`${t}: ${r}\r\n`;return e}getResponseHeader(e){return this.#d?this.#d.headers.get(e):""}open(e,t,r,n,s){if(console.log("DEBUG XHR.open",this,e,t,r,n,s),!1===r)throw new DOMException("InvalidAccessError");this.#b(),this.readyState=this.OPENED,this.#m=new URL(t,x.location.href),this.#m.username=n||"",this.#m.password=s||"",this.#y.headers={},this.#y.method=e}overrideMimeType(e){this.#_=e}send(e){console.log("DEBUG XHR.send",this,e),this.timeout&&setTimeout((()=>{this.readyState!==this.DONE&&this.abort()}),this.timeout),this.#y.body=e,(async()=>{try{if(this.#d=await K(this.#m,this.#y),this.readyState=this.HEADERS_RECEIVED,this.readyState=this.LOADING,this.#w)return;this.#E(new ProgressEvent("loadstart")),this.#f=await this.#d.arrayBuffer(),this.#E(new ProgressEvent("progress")),this.readyState=this.DONE,this.#E(new ProgressEvent("load"))}catch(e){this.#E(new ProgressEvent("error"))}this.#E(new ProgressEvent("loadend"))})()}setRequestHeader(e,t){this.#y.headers||(this.#y.headers={}),this.#y.headers[e]=t}set readyState(e){this.#p=e,this.#E(new Event("readystatechange"))}get readyState(){return this.#p}get response(){if(null!==this.#f)return"blob"===this.responseType?new Blob([this.#f]):"arraybuffer"===this.responseType?this.#f:this.responseText}get responseText(){return this.#f?(new TextDecoder).decode(this.#f):""}get responseURL(){return this.#d?this.#d.url:""}get responseXML(){if("document"!==this.responseType&&""!==this.responseType)throw new DOMException("InvalidStateError");if(null===this.#d)return null;if(null===this.#f)throw new DOMException("InvalidStateError");return(new DOMParser).parseFromString(this.responseText,this.#_)}get status(){return this.#d?this.#d.status:0}get statusText(){return this.#d?this.#d.statusText:""}get upload(){return this.#g}}const O={currentScript:null,activeElement:null},S=new class{get cookie(){return""}set cookie(e){}get body(){return this.__target__.body}get location(){return x.location}get URL(){return x.location.href}get currentScript(){return O.currentScript}set currentScript(e){O.currentScript=e}get activeElement(){return O.activeElement||document.body}set activeElement(e){O.activeElement=e}createElement(e,t){return this.__target__.createElement(e,t)}};function L(e){re(e)}A(globalThis?.HTMLElement?.prototype,"append",((e,t,r)=>(L(r[0]),Reflect.apply(e,t,r)))),A(globalThis?.HTMLElement?.prototype,"appendChild",((e,t,r)=>(L(r[0]),Reflect.apply(e,t,r)))),A(globalThis?.HTMLElement?.prototype,"insertBefore",((e,t,r)=>(L(r[0]),Reflect.apply(e,t,r)))),A(globalThis?.HTMLElement?.prototype,"replaceChild",((e,t,r)=>(L(r[0]),Reflect.apply(e,t,r)))),globalThis.Image&&(globalThis.Image=new Proxy(globalThis.Image,{construct(e,t){let r=Reflect.construct(e,t);return re(r),r}})),"undefined"!=typeof Navigator&&(Navigator.prototype.sendBeacon=()=>{}),"undefined"!=typeof MutationObserver&&(MutationObserver.prototype.observe=new Proxy(MutationObserver.prototype.observe,{apply:(e,t,r)=>(r[0]===x.document&&(r[0]=x.document.documentElement),Reflect.apply(e,t,r))}));const M="function"==typeof importScripts,R={location:null,self:null,globalThis:null,eval:null,history:null,localStorage:null,sessionStorage:null},x=new class{set location(e){R.location.assign(e)}get location(){return R.location}set self(e){R.self=e}get self(){return R.self}set globalThis(e){R.globalThis=e}get globalThis(){return R.globalThis}get window(){return this}get origin(){return this.location.origin}get document(){return M?void 0:S}fetch(){return async function(e,t={}){console.log("DEBUG fetch",e,t);let r=e;e instanceof Request&&(r=e.url,t.body=t.body||await e.blob(),t.headers=t.headers||Object.fromEntries(e.headers),t.method=t.method||e.method),r=new URL(r,x.location.href).href,t.body instanceof ReadableStream&&(t.duplex="half"),t.signal&&delete t.signal;let n=new Request("http://127.0.0.1/",t),s=await n.arrayBuffer();return t.body=s.byteLength?s:void 0,await K(r,t)}(...arguments)}get URL(){return y}get Worker(){return E}get importScripts(){return M?v:void 0}get XMLHttpRequest(){return T}get history(){return R.history}get localStorage(){return R.localStorage}get sessionStorage(){return R.sessionStorage}get WebSocket(){return Q}};function A(e,t,r){e&&(e[t]=new Proxy(e[t],{apply:r}))}function P(e,t,r){t[e]=new Proxy(r[e],{apply:function(e,t,n){return Reflect.apply(e,r,n)}})}function N(e,t){e.__target__=t;let r=Object.getPrototypeOf(e),n=Reflect.ownKeys(t),s=Object.getPrototypeOf(t);for(;null!=s;)n.push(...Reflect.ownKeys(s)),s=Object.getPrototypeOf(s);let o=["eval"];for(let s of n)if(!r.hasOwnProperty(s)&&"__proto__"!==s&&!o.includes(s))try{if("function"==typeof t[s]){P(s,e,t);continue}try{e[s]=t[s]}catch{Object.defineProperty(e,s,{configurable:!0,value:t[s],writable:!0})}}catch(e){if(e instanceof DOMException)continue;if(e instanceof TypeError)continue}}function k(){R.location=new m,R.self=x,R.globalThis=x,R.history=new w,R.localStorage=new b("local"),R.sessionStorage=new b("session"),N(x,globalThis),delete x.eval;for(let e of Reflect.ownKeys(globalThis))e.startsWith("on")&&Object.defineProperty(x,e,{get:()=>globalThis[e],set:t=>{globalThis[e]=t}})}function I(e,t){return new URL(e,t).href}function U(e){return`\n try {\n ${e}\n }\n catch (__e__) {\n console.error(__e__);\n }\n `}function D(e,t=x){H(U(e),t)}function H(e,t=x){return Reflect.apply(Function("globalThis",`\n with (globalThis) {\n ${e}\n }\n `),t,[x])}function q(e,t,r){let n=Object.getOwnPropertyDescriptor(Object.getPrototypeOf(e),t);if(n)return Object.defineProperty(e,t,r),n}const j=p("parent","fetch"),C=p("parent","ws_new"),B=p("parent","ws_event"),$=p("parent","ws_send"),W=p("parent","ws_close"),G={},F={};let V=!1;function X(e=!0){V=e}function J(e,t){F[e]=t}async function K(e,t){if(!V)throw"Network request blocked";let r=x.location?.href||ce;if("data:"===(e=new URL(e,r)).protocol||"blob:"===e.protocol)return await globalThis.fetch(e.href,t);if("http:"!==e.protocol&&"https:"!==e.protocol)throw TypeError("Invalid URL");let n=await j(e.href,t),s=new Response(n.body);for(let e in n.items)Object.defineProperty(s,e,{value:n.items[e]});let o=new Headers;for(let[e,t]of n.headers)o.append(e,t);return Object.defineProperty(s,"headers",{value:o}),s}function z(e,t=null){let r=URL.createObjectURL(e);return t&&(G[r]=t),r}class Q extends EventTarget{#T;constructor(e,t=[]){super(),this.url=e,this.protocols=t,this.binaryType="blob",this.bufferedAmount=0,this.onopen=()=>{},this.onerror=()=>{},this.onmessage=()=>{},this.onclose=()=>{},this.CONNECTING=0,this.OPEN=1,this.CLOSING=2,this.CLOSED=3,this.status=this.CONNECTING,this.#T=null,this.#O()}async#O(){this.#T=await C(ue,this.url,this.protocols,{headers:{Origin:x.location.origin}}),this.#S()}async#S(){for(;;){let e=await B(ue,this.#T);if(!e)break;for(let[t,r]of e)this.#L(t,r)}}#L(e,t){if("open"===e)this.status=this.OPEN,this.#M(new Event("open"));else if("close"===e)this.status=this.CLOSED,this.#M(new CloseEvent("close"));else if("message"===e){let e;e="string"==typeof t?t:"arraybuffer"==this.binaryType?t.buffer:new Blob([t]),this.#M(new MessageEvent("message",{data:e}))}else"error"===e&&this.#M(new Event("error"))}#M(e){try{this["on"+e.type](e)}catch(e){console.error(e)}this.dispatchEvent(e)}send(e){if(this.status===this.CONNECTING)throw new DOMException("Websocket not ready yet.");if(this.status!==this.CLOSED)if(e instanceof Blob)(async()=>{let t=await e.arrayBuffer();this.send(new Uint8Array(t))})();else if("string"==typeof e)$(ue,this.#T,e);else{let t=function(e){if(e instanceof Uint8Array)return e;if("string"==typeof e)return(new TextEncoder).encode(e);if(e instanceof ArrayBuffer)return new Uint8Array(e);if(ArrayBuffer.isView(e))return new Uint8Array(e.buffer);throw new TypeError("invalid data type to be sent")}(e);$(ue,this.#T,t)}}close(){this.status=this.CLOSING,W(ue,this.#T)}}const Y=/url\(['"]?(.+?)['"]?\)/gm;function Z(e,t){let r=[...e.matchAll(Y)];if(!r.length)return e;let n={};for(let e of r){let r=e[1];r.startsWith("data:")||r.startsWith("blob:")||n[r]||(n[r]=(async()=>{let e=I(r,t),n=await K(e);return[r,await n.blob()]})())}return n?(async()=>{let t=await _(Object.values(n));t.filter((e=>e));let r=Object.fromEntries(t);return ee(e,r)})():ee(e,{})}function ee(e,t){return e.replaceAll(Y,((e,r)=>{if(r.startsWith("data:")||r.startsWith("blob:"))return e;return`url("${z(t[r],r)}")`}))}function te(e){let t;var r;"NOSCRIPT"===e.tagName?t=function(e){let t=new Comment(e.innerHTML);e.innerHTML="",e.append(t)}(e):e.matches("img, source, video, audio")?t=function(e){let t=e.src;if(e instanceof HTMLVideoElement){let t=e.querySelector("source[src]");for(;e.lastChild!==t;)e.lastChild.remove()}let r="",n=q(e,"src",{get:()=>r||n.get.call(e),set(t){(function(e){let t=new URL(e,"http://example.com/");return"http:"===t.protocol||"https:"===t.protocol})(t)&&t?(e.src="",(async t=>{e.setAttribute("__src",t),r=I(t,x.location.href);let n=await K(r),s=await n.blob(),o=URL.createObjectURL(s);if(e.src=o,e instanceof HTMLSourceElement){let t=e.parentNode;for(;t&&!(t instanceof HTMLVideoElement);)t=t.parentNode;if(!t)return;if(t.load(),!t.autoplay)return;t.play()}})(t)):n.set.call(e,t)}});A(e,"setAttribute",((t,r,n)=>{if("src"!==n[0])return Reflect.apply(t,r,n);e.src=n[1]})),!t||t.startsWith("data:")||t.startsWith("blob:")||(e.getAttribute("srcset")&&e.setAttribute("srcset",""),e.src=t)}(e):e instanceof HTMLLinkElement&&"stylesheet"!==e.rel?t=void("icon"!==(r=e).rel&&(r.rel="__"+r.rel)):e instanceof HTMLMetaElement?t=function(e){if(!e.getAttribute("http-equiv"))return;if("refresh"!==e.getAttribute("http-equiv"))return;e.setAttribute("http-equiv","");let t=e.getAttribute("content");if(!t)return;let r=t.match(/(\d+)([;,] ?url=['"]?(.+?)['"]?)?$/im),[n,s,o,i]=r;s&&n&&(i||(i="/"),i=I(i,x.location.href),setTimeout((()=>{ie(ue,i)}),1e3*parseInt(s)))}(e):e instanceof HTMLLinkElement&&"stylesheet"===e.rel?t=async function(e){let t=e.href||e.getAttribute("data-href");if(!t)return;let r=I(t,x.location.href),n=await K(r),s=await n.text(),o=await Z(s,r),i=new Blob([o],{type:"text/css"});e.href=z(i,n.url)}(e):e instanceof HTMLStyleElement?t=async function(e){let t=e.innerHTML;e.innerHTML=await Z(t,x.location.href)}(e):e instanceof HTMLScriptElement?t=async function(e){if(!oe(e))return;let t=e.innerHTML,r=e.src;async function n(){let e=I(r,x.location.href),n=await K(e);t=await n.text()}function s(){x.document.currentScript=e,D(t),x.document.currentScript=null,e.dispatchEvent(new Event("load"))}if(q(e,"src",{get:()=>r,set:async e=>{r=e,await n(),s()}}),e.removeAttribute("src"),r&&await n(),he)s();else{let r=""+Math.random();e.setAttribute("__script_id",r),se[r]=t}}(e):e instanceof HTMLFormElement&&(t=function(e){e.setAttribute=new Proxy(e.setAttribute,{apply:(e,t,r)=>("action"!==r[0]||r[1].startsWith("data:")||(r[1]=function(e){let t=I(e,x.location.href);return`data:text/html,${ne.replace("__ORIGINAL_URL__",t).replace("__FRAME_ID__",ue)}`}(r[1])),e.apply(t,r))});let t=e.getAttribute("action");t&&e.setAttribute("action",t)}(e));let n=[t];for(let t=0;t<e.attributes.length;t++){let r=e.attributes[t].name;if(!r.startsWith("on"))continue;let n=e.getAttribute(r),s=r.substring(2);e.setAttribute("__"+r,n),e.removeAttribute(r),e.addEventListener(s,(()=>{H(n,e)}))}let s=e.getAttribute("style");if(s){e.style.cssText="";let t=Z(s,x.location.href);"string"==typeof t?e.style.cssText=t:n.push((async()=>{e.style.cssText=await t})())}return e.addEventListener("focus",(()=>{x.document.activeElement=e})),n}function re(e){if(!(e instanceof Element))return;let t=[];e.__rewritten__||(e.__rewritten__=!0,t=te(e));let r=[...e.children];for(let e of r)t.push(re(e));return t=t.filter((e=>e)),t?Promise.all(t):void 0}const ne='\n <style>\n html {\n background-color: rgb(34, 34, 34);\n }\n </style>\n <script>\n let original_url = "__ORIGINAL_URL__";\n let frame_id = "__FRAME_ID__";\n window.onload = () => {\n let url_params = document.body.textContent;\n let new_url = original_url + url_params;\n document.body.textContent = "";\n top.postMessage({\n type: "procedure",\n id: Math.random() + "",\n procedure: "navigate",\n arguments: [frame_id, new_url]\n }, {targetOrigin: "*"});\n }\n <\/script>\n',se={};function oe(e){return!e.type||"application/javascript"===e.type||"text/javascript"===e.type}const ie=p("parent","navigate"),ae=p("parent","local_storage"),le=self.document?.currentScript?.innerHTML;let ce,ue,he=!1;function pe(e){ue=e}function de(e){ce=e}a.html=async function(e){if(G[location.href]=e.url,X(),de(e.url),pe(e.frame_id),k(),e.error)return document.getElementById("loading_text").style.display="none",document.getElementById("error_div").style.display="initial",document.getElementById("error_msg").innerText=e.error,void(document.getElementById("version_text").innerText=`Sandstone v${e.version.ver} (${e.version.hash})`);if(e.local_storage)for(let[t,r]of e.local_storage)x.localStorage.setItem(t,r);let t=(new DOMParser).parseFromString(e.html,"text/html");await re(t.documentElement),document.addEventListener("click",(e=>{if(e.defaultPrevented)return;let t=e.target;for(;t&&!(t instanceof HTMLAnchorElement);)t=t.parentElement;if(!t)return;let r=I(t.href,x.location.href);ie(ue,r),e.preventDefault(),e.stopImmediatePropagation()}));let r=t.querySelectorAll("*[id]"),n=Object.getPrototypeOf(x);for(let e=0;e<r.length;e++){let t=r[e];n.hasOwnProperty(t.id)||(x[t.id]=t)}console.log("done downloading page"),document.documentElement.replaceWith(t.documentElement),N(S,document),function(){let e=document.getElementsByTagName("script"),t=[];for(let r=0;r<e.length;r++){let n=e[r];if(n.hasAttribute("__script_id")){let e=n.getAttribute("__script_id");t.push([e,se[e]]),delete se[e]}else oe(n)&&t.push([script_id,n.innerHTML])}let r=[];for(let[e,n]of t){let t=`\n document.currentScript = document.querySelector("script[__script_id='${e}']");\n ${U(n)}\n document.currentScript = null;\n `;r.push(t)}H(r.join("\n\n"))}(),he=!0,x.document.dispatchEvent(new Event("DOMContentLoaded")),x.document.dispatchEvent(new Event("load")),x.dispatchEvent(new Event("load"))},a.favicon=async function(){for(var e="/favicon.ico",t=document.getElementsByTagName("link"),r=0;r<t.length;r++){let n=t[r];"icon"===n.getAttribute("rel")&&(e=n.getAttribute("href")),"shortcut icon"===n.getAttribute("rel")&&(e=n.getAttribute("href"))}let n=await K(e);return n.ok?await n.blob():null},a.eval=function(e){D(e)},d("frame"),sandstone_frame=t})();