diff --git a/.eslintrc.json b/.eslintrc.json index 8fa738e8..d2b15459 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -5,7 +5,7 @@ }, "extends": "eslint:recommended", "parserOptions": { - "ecmaVersion": 12, + "ecmaVersion": "latest", "sourceType": "module" }, "ignorePatterns": ["__template.js", "xworker.js", "esm/python/*.js", "esm/3rd-party/*"], diff --git a/docs/README.md b/docs/README.md index 56ddeb40..129d5359 100644 --- a/docs/README.md +++ b/docs/README.md @@ -379,6 +379,7 @@ The module is registered within the interpreter as *JS* module and it offers var | currentScript | `from polyscript import currentScript` | it's an explicit, always correct, reference to the current node running the generic script code. | | js_modules | `from polyscript import js_modules` | described in the [Extra config Features](#extra-config-features) part. | | lazy_py_modules | `from polyscript import lazy_py_modules` | allows, only in *Python* related interpreters, and without needing static config entries, to import lazily any available module. +| storage | `from polyscript import storage` | a utility to instantiate a named [idb-map](https://github.com/WebReflection/idb-map/#readme) that can be consumed synchronously. #### lazy_py_modules @@ -393,6 +394,26 @@ The module is registered within the interpreter as *JS* module and it offers var ``` +#### storage + +```html + +``` + + ### Worker exports diff --git a/docs/index.js b/docs/index.js index 591aa71e..85851bfc 100644 --- a/docs/index.js +++ b/docs/index.js @@ -1,3 +1,3 @@ -const e=(e,t=document)=>[...t.querySelectorAll(e)],t=(e,t=document)=>{const n=(new XPathEvaluator).createExpression(e).evaluate(t,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE),r=[];for(let e=0,{snapshotLength:t}=n;e"function"==typeof e,s={get:(e,t)=>n.hasOwnProperty(t)?((e,t,{get:n,value:s})=>n||!r(s)?e.then((e=>e[t])):(...n)=>e.then((e=>e[t](...n))))(e,t,n[t]):((e,t)=>r(t)?t.bind(e):t)(e,e[t])};var o=(e,...t)=>new Proxy(fetch(e,...t),s);const a="object"==typeof self?self:globalThis,i=e=>((e,t)=>{const n=(t,n)=>(e.set(n,t),t),r=s=>{if(e.has(s))return e.get(s);const[o,i]=t[s];switch(o){case 0:case-1:return n(i,s);case 1:{const e=n([],s);for(const t of i)e.push(r(t));return e}case 2:{const e=n({},s);for(const[t,n]of i)e[r(t)]=r(n);return e}case 3:return n(new Date(i),s);case 4:{const{source:e,flags:t}=i;return n(new RegExp(e,t),s)}case 5:{const e=n(new Map,s);for(const[t,n]of i)e.set(r(t),r(n));return e}case 6:{const e=n(new Set,s);for(const t of i)e.add(r(t));return e}case 7:{const{name:e,message:t}=i;return n(new a[e](t),s)}case 8:return n(BigInt(i),s);case"BigInt":return n(Object(BigInt(i)),s)}return n(new a[o](i),s)};return r})(new Map,e)(0),c="",{toString:l}={},{keys:p}=Object,u=e=>{const t=typeof e;if("object"!==t||!e)return[0,t];const n=l.call(e).slice(8,-1);switch(n){case"Array":return[1,c];case"Object":return[2,c];case"Date":return[3,c];case"RegExp":return[4,c];case"Map":return[5,c];case"Set":return[6,c]}return n.includes("Array")?[1,n]:n.includes("Error")?[7,n]:[2,n]},f=([e,t])=>0===e&&("function"===t||"symbol"===t),d=(e,{json:t,lossy:n}={})=>{const r=[];return((e,t,n,r)=>{const s=(e,t)=>{const s=r.push(e)-1;return n.set(t,s),s},o=r=>{if(n.has(r))return n.get(r);let[a,i]=u(r);switch(a){case 0:{let t=r;switch(i){case"bigint":a=8,t=r.toString();break;case"function":case"symbol":if(e)throw new TypeError("unable to serialize "+i);t=null;break;case"undefined":return s([-1],r)}return s([a,t],r)}case 1:{if(i)return s([i,[...r]],r);const e=[],t=s([a,e],r);for(const t of r)e.push(o(t));return t}case 2:{if(i)switch(i){case"BigInt":return s([i,r.toString()],r);case"Boolean":case"Number":case"String":return s([i,r.valueOf()],r)}if(t&&"toJSON"in r)return o(r.toJSON());const n=[],c=s([a,n],r);for(const t of p(r))!e&&f(u(r[t]))||n.push([o(t),o(r[t])]);return c}case 3:return s([a,r.toISOString()],r);case 4:{const{source:e,flags:t}=r;return s([a,{source:e,flags:t}],r)}case 5:{const t=[],n=s([a,t],r);for(const[n,s]of r)(e||!f(u(n))&&!f(u(s)))&&t.push([o(n),o(s)]);return n}case 6:{const t=[],n=s([a,t],r);for(const n of r)!e&&f(u(n))||t.push(o(n));return n}}const{message:c}=r;return s([a,{name:i,message:c}],r)};return o})(!(t||n),!!t,new Map,r)(e),r},{parse:h,stringify:g}=JSON,y={json:!0,lossy:!0};var w=Object.freeze({__proto__:null,parse:e=>i(h(e)),stringify:e=>g(d(e,y))});const m="64e10b34-2bf7-4616-9668-f99de5aa046e",b="M"+m,_="T"+m,v="array",E="function",k="null",x="number",T="object",S="string",A="symbol",O="undefined",R="apply",j="construct",$="defineProperty",P="deleteProperty",M="get",I="getOwnPropertyDescriptor",N="getPrototypeOf",F="has",W="isExtensible",H="ownKeys",D="preventExtensions",L="set",C="setPrototypeOf",U="delete",{isArray:B}=Array;let{SharedArrayBuffer:J,window:q}=globalThis,{notify:z,wait:G,waitAsync:K}=Atomics,Y=null;K||(K=e=>({value:new Promise((t=>{let n=new Worker("data:application/javascript,onmessage%3D(%7Bdata%3Ab%7D)%3D%3E(Atomics.wait(b%2C0)%2CpostMessage(0))");n.onmessage=t,n.postMessage(e)}))}));try{new J(4)}catch(e){J=ArrayBuffer;const t=new WeakMap;if(q){const e=new Map,{prototype:{postMessage:n}}=Worker,r=t=>{const n=t.data?.[m];if(!B(n)){t.stopImmediatePropagation();const{id:r,sb:s}=n;e.get(r)(s)}};Y=function(e,...s){const o=e?.[m];if(B(o)){const[e,n]=o;t.set(n,e),this.addEventListener("message",r)}return n.call(this,e,...s)},K=n=>({value:new Promise((r=>{e.set(t.get(n),r)})).then((r=>{e.delete(t.get(n)),t.delete(n);for(let e=0;e({[m]:{id:e,sb:t}});z=n=>{postMessage(e(t.get(n),n))},addEventListener("message",(e=>{const n=e.data?.[m];if(B(n)){const[e,r]=n;t.set(r,e)}}))}} -/*! (c) Andrea Giammarchi - ISC */const{Int32Array:X,Map:V,Uint16Array:Z}=globalThis,{BYTES_PER_ELEMENT:Q}=X,{BYTES_PER_ELEMENT:ee}=Z,te=new WeakSet,ne=new WeakMap,re={value:{then:e=>e()}};let se=0;const oe=(e,{parse:t=JSON.parse,stringify:n=JSON.stringify,transform:r,interrupt:s}=JSON)=>{if(!ne.has(e)){const o=Y||e.postMessage,a=(t,...n)=>o.call(e,{[m]:n},{transfer:t}),i=typeof s===E?s:s?.handler,c=s?.delay||42,l=new TextDecoder("utf-16"),p=(e,t)=>e?K(t,0):(i?((e,t,n)=>{for(;"timed-out"===G(e,0,0,t);)n()})(t,c,i):G(t,0),re);let u=!1;ne.set(e,new Proxy(new V,{[F]:(e,t)=>"string"==typeof t&&!t.startsWith("_"),[M]:(n,s)=>"then"===s?null:(...n)=>{const o=se++;let i=new X(new J(2*Q)),c=[];te.has(n.at(-1)||c)&&te.delete(c=n.pop()),a(c,o,i,s,r?n.map(r):n);const f=e!==globalThis;let d=0;return u&&f&&(d=setTimeout(console.warn,1e3,`πŸ’€πŸ”’ - Possible deadlock if proxy.${s}(...args) is awaited`)),p(f,i).value.then((()=>{clearTimeout(d);const e=i[1];if(!e)return;const n=ee*e;return i=new X(new J(n+n%Q)),a([],o,i),p(f,i).value.then((()=>t(l.decode(new Z(i.buffer).slice(0,e)))))}))},[L](t,s,o){const a=typeof o;if(a!==E)throw new Error(`Unable to assign ${s} as ${a}`);if(!t.size){const s=new V;e.addEventListener("message",(async e=>{const o=e.data?.[m];if(B(o)){e.stopImmediatePropagation();const[a,i,...c]=o;let l;if(c.length){const[e,o]=c;if(t.has(e)){u=!0;try{const c=await t.get(e)(...o);if(void 0!==c){const e=n(r?r(c):c);s.set(a,e),i[1]=e.length}}catch(e){l=e}finally{u=!1}}else l=new Error(`Unsupported action: ${e}`);i[0]=1}else{const e=s.get(a);s.delete(a);for(let t=new Z(i.buffer),n=0;n(te.add(e),e);const{isArray:ae}=Array,ie=(e,t)=>t,ce=e=>typeof e===E?(e=>e())(e):e;function le(){return this}const pe=(e,t)=>e===v?[t]:{t:e,v:t},ue=(e,t=ie)=>{let n=typeof e,r=e;return n===T&&(ae(e)?(n=v,r=e.at(0)):({t:n,v:r}=e)),t(n,r)},fe=(e,t)=>e===E?t:pe(e,t),de=(e,t=fe)=>{const n=null===e?k:typeof e;return t(n===T&&ae(e)?v:n,e)},he=new FinalizationRegistry((([e,t,n])=>{n&&console.debug(`Held value ${String(t)} not relevant anymore`),e(t)})),ge=Object.create(null),ye=(e,t,{debug:n,handler:r,return:s,token:o=e}=ge)=>{const a=s||new Proxy(e,r||ge),i=[a,[t,e,!!n]];return!1!==o&&i.push(o),he.register(...i),a},{defineProperty:we,deleteProperty:me,getOwnPropertyDescriptor:be,getPrototypeOf:_e,isExtensible:ve,ownKeys:Ee,preventExtensions:ke,set:xe,setPrototypeOf:Te}=Reflect,{assign:Se,create:Ae}=Object,Oe=_e(Int8Array),Re=(e,t)=>{const{get:n,set:r,value:s}=e;return n&&(e.get=t(n)),r&&(e.set=t(r)),s&&(e.value=t(s)),e},je=e=>t=>de(t,((t,n)=>{switch(t){case k:return pe(k,n);case T:if(n===globalThis)return pe(t,null);case v:case E:return e(t,n);case"boolean":case x:case S:case O:case"bigint":return pe(t,n);case A:{if($e.has(n))return pe(t,$e.get(n));let e=Symbol.keyFor(n);if(e)return pe(t,`.${e}`)}}throw new TypeError(`Unable to handle this ${t}: ${String(n)}`)})),$e=new Map(Ee(Symbol).filter((e=>typeof Symbol[e]===A)).map((e=>[Symbol[e],e]))),Pe=e=>{if(e.startsWith("."))return Symbol.for(e.slice(1));for(const[t,n]of $e)if(n===e)return t},Me=e=>e;var Ie=((e,t)=>{const n=new WeakMap;{const{addEventListener:e}=EventTarget.prototype;we(EventTarget.prototype,"addEventListener",{value(t,r,...s){return s.at(0)?.invoke&&(n.has(this)||n.set(this,new Map),n.get(this).set(t,[].concat(s[0].invoke)),delete s[0].invoke),e.call(this,t,r,...s)}})}return function(t,r,s,...o){let a=0,i=this?.transform||Me;const c=new Map,l=new Map,{[s]:p}=t,u=o.length?Se(Ae(globalThis),...o):globalThis,f=je(((e,t)=>{if(!c.has(t)){let n;for(;l.has(n=a++););c.set(t,n),l.set(n,e===E?t:i(t))}return pe(e,c.get(t))})),d=e=>{p(U,pe(S,e))},h=(e,t)=>{switch(e){case T:if(null==t)return u;case v:if(typeof t===x)return l.get(t);if(!(t instanceof Oe))for(const e in t)t[e]=g(t[e]);return t;case E:if(typeof t===S){const e=l.get(t)?.deref();if(e)return e;const r=function(...e){return e.at(0)instanceof Event&&(e=>{const{currentTarget:t,target:r,type:s}=e;for(const o of n.get(t||r)?.get(s)||[])e[o]()})(...e),p(R,pe(E,t),f(this),e.map(f))};return l.set(t,new WeakRef(r)),ye(t,d,{return:r,token:!1})}return l.get(t);case A:return Pe(t)}return t},g=e=>ue(e,h),y={[R]:(e,t,n)=>f(e.apply(t,n)),[j]:(e,t)=>f(new e(...t)),[$]:(e,t,n)=>f(we(e,t,n)),[P]:(e,t)=>f(me(e,t)),[N]:e=>f(_e(e)),[M]:(e,t)=>f(e[t]),[I]:(e,t)=>{const n=be(e,t);return n?pe(T,Re(n,f)):pe(O,n)},[F]:(e,t)=>f(t in e),[W]:e=>f(ve(e)),[H]:e=>pe(v,Ee(e).map(f)),[D]:e=>f(ke(e)),[L]:(e,t,n)=>f(xe(e,t,n)),[C]:(e,t)=>f(Te(e,t)),[U](e){c.delete(l.get(e)),l.delete(e)}};return t[r]=(e,t,...n)=>{switch(e){case R:n[0]=g(n[0]),n[1]=n[1].map(g);break;case j:n[0]=n[0].map(g);break;case $:{const[e,t]=n;n[0]=g(e);const{get:r,set:s,value:o}=t;r&&(t.get=g(r)),s&&(t.set=g(s)),o&&(t.value=g(o));break}default:n=n.map(g)}return y[e](g(t),...n)},{proxy:t,[e.toLowerCase()]:u,[`is${e}Proxy`]:()=>!1}}})("Window"),Ne=(e=>{let t=0;const n=new Map,r=new Map,s=Symbol();return function(o,a,i){const c=this?.transform||Me,{[a]:l}=o,p=new Map,u=e=>{p.delete(e),l(U,f(e))},f=je(((e,o)=>{if(s in o)return ce(o[s]);if(e===E){if(o=c(o),!r.has(o)){let e;for(;r.has(e=String(t++)););n.set(o,e),r.set(e,o)}return pe(e,n.get(o))}if(!(o instanceof Oe)){o=c(o);for(const e in o)o[e]=f(o[e])}return pe(e,o)})),d=(e,t,n)=>{const r=p.get(n)?.deref();if(r)return r;const s=t===E?(e=>le.bind(e))(e):e,o=new Proxy(s,y);return p.set(n,new WeakRef(o)),ye(n,u,{return:o,token:!1})},h=e=>ue(e,((t,n)=>{switch(t){case T:if(null===n)return globalThis;case v:return typeof n===x?d(e,t,n):n;case E:return typeof n===S?r.get(n):d(e,t,n);case A:return Pe(n)}return n})),g=(e,t,...n)=>h(l(e,ce(t),...n)),y={[R]:(e,t,n)=>g(R,e,f(t),n.map(f)),[j]:(e,t)=>g(j,e,t.map(f)),[$]:(e,t,n)=>{const{get:r,set:s,value:o}=n;return typeof r===E&&(n.get=f(r)),typeof s===E&&(n.set=f(s)),typeof o===E&&(n.value=f(o)),g($,e,f(t),n)},[P]:(e,t)=>g(P,e,f(t)),[N]:e=>g(N,e),[M]:(e,t)=>t===s?e:g(M,e,f(t)),[I]:(e,t)=>{const n=g(I,e,f(t));return n&&Re(n,h)},[F]:(e,t)=>t===s||g(F,e,f(t)),[W]:e=>g(W,e),[H]:e=>g(H,e).map(h),[D]:e=>g(D,e),[L]:(e,t,n)=>g(L,e,f(t),f(n)),[C]:(e,t)=>g(C,e,f(t))};o[i]=(e,t,s,o)=>{switch(e){case R:return h(t).apply(h(s),o.map(h));case U:{const e=h(t);n.delete(r.get(e)),r.delete(e)}}};const w=new Proxy(pe(T,null),y);return{[e.toLowerCase()]:w,[`is${e}Proxy`]:e=>typeof e===T&&!!e&&s in e,proxy:o}}})("Window"),Fe=typeof Worker===E?Worker:class{};const We=new WeakMap,He=(e,...t)=>{const n=oe(e,...t);if(!We.has(n)){const r=e instanceof Fe?Ie:Ne;We.set(n,r.call(t.at(0),n,b,_))}return We.get(n)};He.transfer=oe.transfer;const{url:De}=import.meta,Le=/import\((['"])([^)]+?\.js)\1\)/g,Ce=(e,t,n)=>`import(${t}${new URL(n,De).href}${t})`;Promise.withResolvers||(Promise.withResolvers=function(){var e,t,n=new this((function(n,r){e=n,t=r}));return{resolve:e,reject:t,promise:n}});const Ue={object(...e){return this.string(function(e){for(var t=e[0],n=1,r=arguments.length;n",">":">","'":"'","'":"'",""":'"',""":'"'},ze=e=>qe[e],Ge=new WeakMap,Ke=e=>{const t=e||console,n={buffered:Xe,stderr:(t.stderr||console.error).bind(t),stdout:(t.stdout||console.log).bind(t)};return{stderr:(...e)=>n.stderr(...e),stdout:(...e)=>n.stdout(...e),async get(e){const t=await e;return Ge.set(t,n),t}}},Ye=new TextDecoder,Xe=(e,t=10)=>{const n=[];return r=>{if(r instanceof Uint8Array)for(const s of r)s===t?e(Ye.decode(new Uint8Array(n.splice(0)))):n.push(s);else e(r)}},Ve=(e,...t)=>Ue[typeof e](e,...t),Ze=e=>Be.call(e,Je,ze),{isArray:Qe}=Array,{assign:et,create:tt,defineProperties:nt,defineProperty:rt,entries:st}=Object,{all:ot,resolve:at}=new Proxy(Promise,{get:(e,t)=>e[t].bind(e)}),it=(e,t=location.href)=>new URL(e,t.replace(/^blob:/,"")).href;let ct=0;const lt=(e,t)=>({id:e.id||(e.id=`${t}-w${ct++}`),tag:e.tagName}),pt=(e,t,n,r=!1,s=CustomEvent)=>{e.dispatchEvent(new s(`${t}:${n}`,{bubbles:!0,detail:{worker:r}}))},ut=(e,t,n,r)=>({type:t,config:n,interpreter:r,io:Ge.get(r),run:(t,...n)=>e.run(r,t,...n),runAsync:(t,...n)=>e.runAsync(r,t,...n),runEvent:(...t)=>e.runEvent(r,...t)}),ft=e=>e.replace(/^(?:\n|\r\n)/,""),dt=(e,t,n,r)=>{const s=e[t].bind(e);e[t]="run"===t?(e,t,...o)=>{n&&s(e,n,...o);const a=s(e,ft(t),...o);return r&&s(e,r,...o),a}:async(e,t,...o)=>{n&&await s(e,n,...o);const a=await s(e,ft(t),...o);return r&&await s(e,r,...o),a}},ht=Symbol.for("polyscript.js_modules"),gt=new Map;rt(globalThis,ht,{value:gt});const yt=new Proxy(gt,{get:(e,t)=>e.get(t),has:(e,t)=>e.has(t),ownKeys:e=>[...e.keys()]}),wt=(e,t)=>!t.startsWith("_"),mt=(e,t)=>new Proxy(e,{has:wt,get:(e,n)=>e[t][n]}),bt=(e,t,n,r)=>{if("pyodide"===e)return;const s="polyscript.js_modules";for(const e of Reflect.ownKeys(r))t.registerJSModule(n,`${s}.${e}`,mt(r,e));t.registerJSModule(n,s,r)},_t=(e,t)=>import(e).then((e=>{gt.set(t,{...e})})),vt=e=>new Promise(((t,n)=>{document.querySelector(`link[href="${e}"]`)&&t(),document.head.append(et(document.createElement("link"),{rel:"stylesheet",href:e,onload:t,onerror:n}))})),Et=e=>/\.css/i.test(new URL(e).pathname),kt=!globalThis.window,xt=({FS:e,PATH:t,PATH_FS:n},r,s)=>{const o=n.resolve(r),a=t.dirname(o);return e.mkdirTree?e.mkdirTree(a):St(e,a),e.writeFile(o,new Uint8Array(s),{canOwn:!0})},Tt=e=>{const t=e.split("/");return t.pop(),t.join("/")},St=(e,t)=>{const n=[];for(const r of t.split("/"))"."!==r&&".."!==r&&(n.push(r),r&&e.mkdir(n.join("/")))},At=(e,t)=>{const n=[];for(const e of t.split("/"))switch(e){case"":case".":break;case"..":n.pop();break;default:n.push(e)}return[e.cwd()].concat(n).join("/").replace(/^\/+/,"/")},Ot=e=>{const t=e.map((e=>e.trim().replace(/(^[/]*|[/]*$)/g,""))).filter((e=>""!==e&&"."!==e)).join("/");return e[0].startsWith("/")?`/${t}`:t},Rt=(e,t)=>o(it(e,t)).arrayBuffer(),jt=(e,t,n,r)=>ot((e=>{for(const{files:t,to_file:n,from:r=""}of e){if(void 0!==t&&void 0!==n)throw new Error("Cannot use 'to_file' and 'files' parameters together!");if(void 0===t&&void 0===n&&r.endsWith("/"))throw new Error(`Couldn't determine the filename from the path ${r}, please supply 'to_file' parameter.`)}return e.flatMap((({from:e="",to_folder:t=".",to_file:n,files:r})=>{if(Qe(r))return r.map((n=>({url:Ot([e,n]),path:Ot([t,n])})));const s=n||e.slice(1+e.lastIndexOf("/"));return[{url:e,path:Ot([t,s])}]}))})(n).map((({url:n,path:s})=>Rt(n,r).then((n=>e.writeFile(t,s,n)))))),$t=(e,t)=>t.endsWith("/")?`${t}${e.split("/").pop()}`:t,Pt=(e,t)=>e.replace(/\{.+?\}/g,(e=>{if(!t.has(e))throw new SyntaxError(`Invalid template: ${e}`);return t.get(e)})),Mt=(e,t,n,r)=>ot((e=>{const t=new Map,n=new Set,r=[];for(const[s,o]of st(e))if(/^\{.+\}$/.test(s)){if(t.has(s))throw new SyntaxError(`Duplicated template: ${s}`);t.set(s,Pt(o,t))}else{const e=Pt(s,t),a=$t(e,Pt(o||"./",t));if(n.has(a))throw new SyntaxError(`Duplicated destination: ${a}`);n.add(a),r.push({url:e,path:a})}return r})(n).map((({url:n,path:s})=>Rt(n,r).then((r=>e.writeFile(t,s,r,n)))))),It=({main:e,worker:t},n)=>{const r=[];if(t&&kt)for(let[e,s]of st(t))e=it(e,n),r.push(_t(e,s));if(e&&!kt)for(let[t,s]of st(e))t=it(t,n),Et(t)?vt(t):r.push(_t(t,s));return ot(r)},Nt=new WeakMap,Ft=(e,t,n)=>{"polyscript"===t&&(n.lazy_py_modules=async(...t)=>(await Nt.get(e)(t),t.map((t=>e.pyimport(t))))),e.registerJsModule(t,n)},Wt=(e,t)=>{if(e.endsWith("/*")){if(/\.(zip|whl|tgz|tar(?:\.gz)?)$/.test(t))return RegExp.$1;throw new Error(`Unsupported archive ${t}`)}return""},Ht=(e,t,...n)=>{try{return e.runPython(Ve(t),...n)}catch(t){Ge.get(e).stderr(t)}},Dt=async(e,t,...n)=>{try{return await e.runPythonAsync(Ve(t),...n)}catch(t){Ge.get(e).stderr(t)}},Lt=async(e,t,n)=>{const[r,...s]=t.split(".");let o,a=e.globals.get(r);for(const e of s)[o,a]=[a,a[e]];try{await a.call(o,n)}catch(t){Ge.get(e).stderr(t)}};var Ct=(new TextEncoder).encode('from uio import StringIO\nimport sys\n\nclass Response:\n def __init__(self, f):\n self.raw = f\n self.encoding = "utf-8"\n self._cached = None\n\n def close(self):\n if self.raw:\n self.raw.close()\n self.raw = None\n self._cached = None\n\n @property\n def content(self):\n if self._cached is None:\n try:\n self._cached = self.raw.read()\n finally:\n self.raw.close()\n self.raw = None\n return self._cached\n\n @property\n def text(self):\n return str(self.content, self.encoding)\n\n def json(self):\n import ujson\n\n return ujson.loads(self.content)\n\n\n# TODO try to support streaming xhr requests, a-la pyodide-http\nHEADERS_TO_IGNORE = ("user-agent",)\n\n\ntry:\n import js\nexcept Exception as err:\n raise OSError("This version of urequests can only be used in the browser")\n\n# TODO try to support streaming xhr requests, a-la pyodide-http\n\nHEADERS_TO_IGNORE = ("user-agent",)\n\n\ndef request(\n method,\n url,\n data=None,\n json=None,\n headers={},\n stream=None,\n auth=None,\n timeout=None,\n parse_headers=True,\n):\n from js import XMLHttpRequest\n\n xhr = XMLHttpRequest.new()\n xhr.withCredentials = False\n\n if auth is not None:\n import ubinascii\n\n username, password = auth\n xhr.open(method, url, False, username, password)\n else:\n xhr.open(method, url, False)\n\n for name, value in headers.items():\n if name.lower() not in HEADERS_TO_IGNORE:\n xhr.setRequestHeader(name, value)\n\n if timeout:\n xhr.timeout = int(timeout * 1000)\n\n if json is not None:\n assert data is None\n import ujson\n\n data = ujson.dumps(json)\n # s.write(b"Content-Type: application/json\\r\\n")\n xhr.setRequestHeader("Content-Type", "application/json")\n\n xhr.send(data)\n\n # Emulates the construction process in the original urequests\n resp = Response(StringIO(xhr.responseText))\n resp.status_code = xhr.status\n resp.reason = xhr.statusText\n resp.headers = xhr.getAllResponseHeaders()\n\n return resp\n\n\n# Other methods - head, post, put, patch, delete - are not used by\n# mip and therefore not included\n\n\ndef get(url, **kw):\n return request("GET", url, **kw)\n\n\n# Content below this line is from the Micropython MIP package and is covered\n# by the applicable MIT license:\n# \n# THE SOFTWARE IS PROVIDED β€œAS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, \n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER \n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING \n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER \n# DEALINGS IN THE SOFTWARE.\n\n# MicroPython package installer\n# MIT license; Copyright (c) 2022 Jim Mussared\n\n\n_PACKAGE_INDEX = const("https://micropython.org/pi/v2")\n_CHUNK_SIZE = 128\n\n\n# This implements os.makedirs(os.dirname(path))\ndef _ensure_path_exists(path):\n import os\n\n split = path.split("/")\n\n # Handle paths starting with "/".\n if not split[0]:\n split.pop(0)\n split[0] = "/" + split[0]\n\n prefix = ""\n for i in range(len(split) - 1):\n prefix += split[i]\n try:\n os.stat(prefix)\n except:\n os.mkdir(prefix)\n prefix += "/"\n\n\n# Copy from src (stream) to dest (function-taking-bytes)\ndef _chunk(src, dest):\n buf = memoryview(bytearray(_CHUNK_SIZE))\n while True:\n n = src.readinto(buf)\n if n == 0:\n break\n dest(buf if n == _CHUNK_SIZE else buf[:n])\n\n\n# Check if the specified path exists and matches the hash.\ndef _check_exists(path, short_hash):\n import os\n\n try:\n import binascii\n import hashlib\n\n with open(path, "rb") as f:\n hs256 = hashlib.sha256()\n _chunk(f, hs256.update)\n existing_hash = str(binascii.hexlify(hs256.digest())[: len(short_hash)], "utf-8")\n return existing_hash == short_hash\n except:\n return False\n\n\ndef _rewrite_url(url, branch=None):\n if not branch:\n branch = "HEAD"\n if url.startswith("github:"):\n url = url[7:].split("/")\n url = (\n "https://raw.githubusercontent.com/"\n + url[0]\n + "/"\n + url[1]\n + "/"\n + branch\n + "/"\n + "/".join(url[2:])\n )\n return url\n\n\ndef _download_file(url, dest):\n response = get(url)\n try:\n if response.status_code != 200:\n print("Error", response.status_code, "requesting", url)\n return False\n\n print("Copying:", dest)\n _ensure_path_exists(dest)\n with open(dest, "wb") as f:\n _chunk(response.raw, f.write)\n\n return True\n finally:\n response.close()\n\n\ndef _install_json(package_json_url, index, target, version, mpy):\n response = get(_rewrite_url(package_json_url, version))\n try:\n if response.status_code != 200:\n print("Package not found:", package_json_url)\n return False\n\n package_json = response.json()\n finally:\n response.close()\n for target_path, short_hash in package_json.get("hashes", ()):\n fs_target_path = target + "/" + target_path\n if _check_exists(fs_target_path, short_hash):\n print("Exists:", fs_target_path)\n else:\n file_url = "{}/file/{}/{}".format(index, short_hash[:2], short_hash)\n if not _download_file(file_url, fs_target_path):\n print("File not found: {} {}".format(target_path, short_hash))\n return False\n for target_path, url in package_json.get("urls", ()):\n fs_target_path = target + "/" + target_path\n if not _download_file(_rewrite_url(url, version), fs_target_path):\n print("File not found: {} {}".format(target_path, url))\n return False\n for dep, dep_version in package_json.get("deps", ()):\n if not _install_package(dep, index, target, dep_version, mpy):\n return False\n return True\n\n\ndef _install_package(package, index, target, version, mpy):\n if (\n package.startswith("http://")\n or package.startswith("https://")\n or package.startswith("github:")\n ):\n if package.endswith(".py") or package.endswith(".mpy"):\n print("Downloading {} to {}".format(package, target))\n return _download_file(\n _rewrite_url(package, version), target + "/" + package.rsplit("/")[-1]\n )\n else:\n if not package.endswith(".json"):\n if not package.endswith("/"):\n package += "/"\n package += "package.json"\n print("Installing {} to {}".format(package, target))\n else:\n if not version:\n version = "latest"\n print("Installing {} ({}) from {} to {}".format(package, version, index, target))\n\n mpy_version = (\n sys.implementation._mpy & 0xFF if mpy and hasattr(sys.implementation, "_mpy") else "py"\n )\n\n # WARNING: mpy_version fails miserably with 1.22.0-380\n package = "{}/package/{}/{}/{}.json".format(index, "py", package, version)\n\n return _install_json(package, index, target, version, mpy)\n\n\ndef install(package, index=None, target=None, version=None, mpy=True):\n if not target:\n for p in sys.path:\n if p.endswith("/lib"):\n target = p\n break\n else:\n print("Unable to find lib dir in sys.path")\n return\n\n if not index:\n index = _PACKAGE_INDEX\n\n if _install_package(package, index.rstrip("/"), target, version, mpy):\n print("Done")\n else:\n print("Package may be partially installed")\n');const Ut=async e=>(await import("./toml-DiUM0_qs.js")).parse(e),Bt=(e,t)=>{try{e.mkdir(t)}catch(e){}};var Jt={type:"micropython",module:(e="1.23.0")=>`https://cdn.jsdelivr.net/npm/@micropython/micropython-webassembly-pyscript@${e}/micropython.mjs`,async engine({loadMicroPython:e},t,n,r){const{stderr:s,stdout:o,get:a}=Ke({stderr:Xe(console.error),stdout:Xe(console.log)});n=n.replace(/\.m?js$/,".wasm");const i=await a(e({linebuffer:!1,stderr:s,stdout:o,url:n})),c=qt.bind(this,i,r);return Nt.set(i,c),t.files&&await Mt(this,i,t.files,r),t.fetch&&await jt(this,i,t.fetch,r),t.js_modules&&await It(t.js_modules,r),this.writeFile(i,"./mip.py",Ct),t.packages&&await c(t.packages),i},registerJSModule:Ft,run:Ht,runAsync:Dt,runEvent:Lt,transform:(e,t)=>e.PyProxy.toJs(t),writeFile:(e,t,n,r)=>{const{FS:s,_module:{PATH:o,PATH_FS:a}}=e,i={FS:s,PATH:o,PATH_FS:a},c=Wt(t,r);if(c){const r=t.slice(0,-1);switch("./"!==r&&s.mkdir(r),c){case"whl":case"zip":{const e=new Blob([n],{type:"application/zip"});return import("./zip-BxogYCy6.js").then((async({BlobReader:t,Uint8ArrayWriter:n,ZipReader:a})=>{const i=new a(new t(e));for(const e of await i.getEntries()){const{directory:t,filename:a}=e,i=r+a;if(t)Bt(s,i);else{Bt(s,o.dirname(i));const t=await e.getData(new n);s.writeFile(i,t,{canOwn:!0})}}i.close()}))}case"tgz":case"tar.gz":{const t="./_.tar.gz";return xt(i,t,n),void e.runPython(`\n import os, gzip, tarfile\n tar = tarfile.TarFile(fileobj=gzip.GzipFile(fileobj=open("${t}", "rb")))\n for f in tar:\n name = f"${r}{f.name}"\n if f.type == tarfile.DIRTYPE:\n if f.name != "./":\n os.mkdir(name.strip("/"))\n else:\n dir = os.path.dirname(name)\n if not os.path.exists(dir):\n os.mkdir(dir)\n source = tar.extractfile(f)\n with open(name, "wb") as dest:\n dest.write(source.read())\n dest.close()\n tar.close()\n os.remove("${t}")\n `)}}}return xt(i,t,n)}};async function qt(e,t,n){let r;for(const s of n)if(s.endsWith(".whl")){const n=it(s,t),r=await o(n).arrayBuffer();await this.writeFile(e,"./*",r,n)}else r||(r=e.pyimport("mip")),r.install(s)}const zt={dict_converter:Object.fromEntries};let Gt=!1;const Kt=e=>(...t)=>{try{return Gt=!0,e(...t)}finally{Gt=!1}};let Yt=!1;const Xt=()=>{if(Yt)return;Yt=!0;const e=new WeakMap,t=e=>e.destroy(),n=n=>{for(let r=0;r`https://cdn.jsdelivr.net/pyodide/v${e}/full/pyodide.mjs`,async engine({loadPyodide:e},t,n,r){kt||"auto"!==t.experimental_create_proxy||Xt();const{stderr:s,stdout:o,get:a}=Ke(),i=n.slice(0,n.lastIndexOf("/")),c=await a(e({stderr:s,stdout:o,indexURL:i})),l=Zt.bind(c);return Nt.set(c,l),t.files&&await Mt(this,c,t.files,r),t.fetch&&await jt(this,c,t.fetch,r),t.js_modules&&await It(t.js_modules,r),t.packages&&await l(t.packages),c},registerJSModule:Ft,run:Kt(Ht),runAsync:Kt(Dt),runEvent:Kt(Lt),transform:({ffi:{PyProxy:e}},t)=>t instanceof e?t.toJs(zt):t,writeFile:(e,t,n,r)=>{const s=Wt(t,r);if(s)return e.unpackArchive(n,s,{extractDir:t.slice(0,-1)});const{FS:o,PATH:a,_module:{PATH_FS:i}}=e;return xt({FS:o,PATH:a,PATH_FS:i},t,n)}};async function Zt(e){await this.loadPackage("micropip");const t=this.pyimport("micropip");await t.install(e,{keep_going:!0}),t.destroy()}const Qt="ruby-wasm-wasi",en=Qt.replace(/\W+/g,"_");var tn={type:Qt,experimental:!0,module:(e="2.6.1")=>`https://cdn.jsdelivr.net/npm/@ruby/3.2-wasm-wasi@${e}/dist/browser/+esm`,async engine({DefaultRubyVM:e},t,n,r){n=n.replace(/\/browser\/\+esm$/,"/ruby.wasm");const s=await o(n).arrayBuffer(),a=await WebAssembly.compile(s),{vm:i}=await e(a);return t.files&&await Mt(this,i,t.files,r),t.fetch&&await jt(this,i,t.fetch,r),t.js_modules&&await It(t.js_modules,r),i},registerJSModule(e,t,n){t=t.replace(/\W+/g,"__");const r=`__module_${en}_${t}`;globalThis[r]=n,this.run(e,`require "js";$${t}=JS.global[:${r}]`),delete globalThis[r]},run:(e,t,...n)=>e.eval(Ve(t),...n),runAsync:(e,t,...n)=>e.evalAsync(Ve(t),...n),async runEvent(e,t,n){if(/^xworker\.(on\w+)$/.test(t)){const{$1:t}=RegExp,r=`__module_${en}_event`;globalThis[r]=n,this.run(e,`require "js";$xworker.call("${t}",JS.global[:${r}])`),delete globalThis[r]}else{const r=this.run(e,`method(:${t})`);await r.call(t,e.wrap(n))}},transform:(e,t)=>t,writeFile:()=>{throw new Error(`writeFile is not supported in ${Qt}`)}};var nn={type:"wasmoon",module:(e="1.16.0")=>`https://cdn.jsdelivr.net/npm/wasmoon@${e}/+esm`,async engine({LuaFactory:e,LuaLibraries:t},n,r,s){const{stderr:o,stdout:a,get:i}=Ke(),c=await i((new e).createEngine());return c.global.getTable(t.Base,(e=>{c.global.setField(e,"print",a),c.global.setField(e,"printErr",o)})),n.files&&await Mt(this,c,n.files,s),n.fetch&&await jt(this,c,n.fetch,s),n.js_modules&&await It(n.js_modules,s),c},registerJSModule:(e,t,n)=>{e.global.set(t,n)},run:(e,t,...n)=>{try{return e.doStringSync(Ve(t),...n)}catch(t){Ge.get(e).stderr(t)}},runAsync:async(e,t,...n)=>{try{return await e.doString(Ve(t),...n)}catch(t){Ge.get(e).stderr(t)}},runEvent:async(e,t,n)=>{const[r,...s]=t.split(".");let o,a=e.global.get(r);for(const e of s)[o,a]=[a,a[e]];try{await a.call(o,n)}catch(t){Ge.get(e).stderr(t)}},transform:(e,t)=>t,writeFile:({cmodule:{module:{FS:e}}},t,n)=>((e,t,n)=>(St(e,Tt(t)),t=At(e,t),e.writeFile(t,new Uint8Array(n),{canOwn:!0})))(e,t,n)};const rn=new WeakMap,sn=async(e,t)=>{const{shelter:n,destroy:r,io:s}=rn.get(e),{output:o,result:a}=await n.captureR(Ve(t));for(const{type:e,data:t}of o)s[e](t);return ye(a,r,{token:!1})};var on={type:"webr",experimental:!0,module:(e="0.3.3")=>`https://cdn.jsdelivr.net/npm/webr@${e}/dist/webr.mjs`,async engine(e,t,n,r){const{get:s}=Ke(),o=new e.WebR;await s(o.init().then((()=>o)));const a=await new o.Shelter;return rn.set(o,{module:e,shelter:a,destroy:a.destroy.bind(a),io:Ge.get(o)}),t.files&&await Mt(this,o,t.files,r),t.fetch&&await jt(this,o,t.fetch,r),t.js_modules&&await It(t.js_modules,r),o},registerJSModule(e,t){console.warn(`Experimental interpreter: module ${t} is not supported (yet)`)},run:sn,runAsync:sn,async runEvent(e,t,n){await e.evalRVoid(`${t}(event)`,{env:{event:{type:[n.type]}}})},transform:(e,t)=>(console.log("transforming",t),t),writeFile:()=>{}};const an=new Map,cn=new Map,ln=[],pn=[],un=new Proxy(new Map,{get(e,t){if(!e.has(t)){const[n,...r]=t.split("@"),s=an.get(n),o=/^(?:\.?\.?\/|https?:\/\/)/i.test(r)?r.join("@"):s.module(...r);e.set(t,{url:o,module:import(o),engine:s.engine.bind(s)})}const{url:n,module:r,engine:s}=e.get(t);return(e,o)=>r.then((r=>(cn.set(t,e),s(r,e,n,o))))}}),fn=e=>{for(const t of[].concat(e.type))an.set(t,e),ln.push(`script[type="${t}"]`),pn.push(`${t}-`)};for(const e of[Jt,Vt,tn,nn,on])fn(e);const{parse:dn}=JSON,hn=(e,t="./config.txt")=>{let n=typeof e;return"string"===n&&/\.(json|toml|txt)$/.test(e)?n=RegExp.$1:e=t,[it(e),n]},gn=e=>{try{return dn(e)}catch(t){return Ut(e)}},yn=(e,t,n,r={})=>{if(t){const[e,s]=hn(t,n);"json"===s?r=o(e).json():"toml"===s?r=o(e).text().then(Ut):"string"===s?r=gn(t):"object"===s&&t?r=t:"txt"===s&&"string"==typeof r&&(r=gn(r)),t=e}return at(r).then((n=>un[e](n,t)))},wn=(e,t="")=>`${e}@${t}`.replace(/@$/,"");function mn(e=this){return String(e).replace(/^(async\s*)?(\bfunction\b)?(.*?)\(/,((e,t,n,r)=>r&&!n?`${t||""}function ${r}(`:e))}const bn="BeforeRun",_n="AfterRun",vn=[`code${bn}`,`code${bn}Async`,`code${_n}`,`code${_n}Async`],En=["onWorker","onReady",`on${bn}`,`on${bn}Async`,`on${_n}`,`on${_n}Async`];function kn(e,t){const{run:n,runAsync:r}=an.get(this.type);return{...e,run:n.bind(this,t),runAsync:r.bind(this,t)}}const xn=(e,t,n,r,s,o)=>{if(s||o){const a=kn.bind(e,t),i=r?"runAsync":"run",c=e[i];e[i]=r?async function(e,t,...r){s&&await s.call(this,a(e),n);const i=await c.call(this,e,t,...r);return o&&await o.call(this,a(e),n),i}:function(e,t,...r){s&&s.call(this,a(e),n);const i=c.call(this,e,t,...r);return o&&o.call(this,a(e),n),i}}};let Tn=class{constructor(e,t={}){const{main:n,worker:r}=t;this.interpreter=e,this.onWorker=n?.onWorker;for(const e of En.slice(1))this[e]=r?.[e];for(const e of vn)this[e]=r?.[e]}toJSON(){const e={};for(const t of En.slice(1))this[t]&&(e[t]=mn(this[t]));for(const t of vn)this[t]&&(e[t]=Ve(this[t]()));return e}};var Sn=(...e)=>function(t,n){const r=new Worker(URL.createObjectURL(new Blob(['const e="object"==typeof self?self:globalThis,t=t=>((t,n)=>{const r=(e,n)=>(t.set(n,e),e),s=o=>{if(t.has(o))return t.get(o);const[a,i]=n[o];switch(a){case 0:case-1:return r(i,o);case 1:{const e=r([],o);for(const t of i)e.push(s(t));return e}case 2:{const e=r({},o);for(const[t,n]of i)e[s(t)]=s(n);return e}case 3:return r(new Date(i),o);case 4:{const{source:e,flags:t}=i;return r(new RegExp(e,t),o)}case 5:{const e=r(new Map,o);for(const[t,n]of i)e.set(s(t),s(n));return e}case 6:{const e=r(new Set,o);for(const t of i)e.add(s(t));return e}case 7:{const{name:t,message:n}=i;return r(new e[t](n),o)}case 8:return r(BigInt(i),o);case"BigInt":return r(Object(BigInt(i)),o)}return r(new e[a](i),o)};return s})(new Map,t)(0),n="",{toString:r}={},{keys:s}=Object,o=e=>{const t=typeof e;if("object"!==t||!e)return[0,t];const s=r.call(e).slice(8,-1);switch(s){case"Array":return[1,n];case"Object":return[2,n];case"Date":return[3,n];case"RegExp":return[4,n];case"Map":return[5,n];case"Set":return[6,n]}return s.includes("Array")?[1,s]:s.includes("Error")?[7,s]:[2,s]},a=([e,t])=>0===e&&("function"===t||"symbol"===t),i=(e,{json:t,lossy:n}={})=>{const r=[];return((e,t,n,r)=>{const i=(e,t)=>{const s=r.push(e)-1;return n.set(t,s),s},c=r=>{if(n.has(r))return n.get(r);let[l,p]=o(r);switch(l){case 0:{let t=r;switch(p){case"bigint":l=8,t=r.toString();break;case"function":case"symbol":if(e)throw new TypeError("unable to serialize "+p);t=null;break;case"undefined":return i([-1],r)}return i([l,t],r)}case 1:{if(p)return i([p,[...r]],r);const e=[],t=i([l,e],r);for(const t of r)e.push(c(t));return t}case 2:{if(p)switch(p){case"BigInt":return i([p,r.toString()],r);case"Boolean":case"Number":case"String":return i([p,r.valueOf()],r)}if(t&&"toJSON"in r)return c(r.toJSON());const n=[],u=i([l,n],r);for(const t of s(r))!e&&a(o(r[t]))||n.push([c(t),c(r[t])]);return u}case 3:return i([l,r.toISOString()],r);case 4:{const{source:e,flags:t}=r;return i([l,{source:e,flags:t}],r)}case 5:{const t=[],n=i([l,t],r);for(const[n,s]of r)(e||!a(o(n))&&!a(o(s)))&&t.push([c(n),c(s)]);return n}case 6:{const t=[],n=i([l,t],r);for(const n of r)!e&&a(o(n))||t.push(c(n));return n}}const{message:u}=r;return i([l,{name:p,message:u}],r)};return c})(!(t||n),!!t,new Map,r)(e),r},{parse:c,stringify:l}=JSON,p={json:!0,lossy:!0};var u=Object.freeze({__proto__:null,parse:e=>t(c(e)),stringify:e=>l(i(e,p))});const f="64e10b34-2bf7-4616-9668-f99de5aa046e",d="M"+f,h="T"+f,g="array",y="function",w="null",m="number",_="object",b="string",E="symbol",v="undefined",k="apply",x="construct",T="defineProperty",S="deleteProperty",A="get",j="getOwnPropertyDescriptor",R="getPrototypeOf",O="has",P="isExtensible",$="ownKeys",N="preventExtensions",M="set",I="setPrototypeOf",F="delete",{isArray:W}=Array;let{SharedArrayBuffer:H,window:D}=globalThis,{notify:C,wait:L,waitAsync:B}=Atomics,U=null;B||(B=e=>({value:new Promise((t=>{let n=new Worker("data:application/javascript,onmessage%3D(%7Bdata%3Ab%7D)%3D%3E(Atomics.wait(b%2C0)%2CpostMessage(0))");n.onmessage=t,n.postMessage(e)}))}));try{new H(4)}catch(e){H=ArrayBuffer;const t=new WeakMap;if(D){const e=new Map,{prototype:{postMessage:n}}=Worker,r=t=>{const n=t.data?.[f];if(!W(n)){t.stopImmediatePropagation();const{id:r,sb:s}=n;e.get(r)(s)}};U=function(e,...s){const o=e?.[f];if(W(o)){const[e,n]=o;t.set(n,e),this.addEventListener("message",r)}return n.call(this,e,...s)},B=n=>({value:new Promise((r=>{e.set(t.get(n),r)})).then((r=>{e.delete(t.get(n)),t.delete(n);for(let e=0;e({[f]:{id:e,sb:t}});C=n=>{postMessage(e(t.get(n),n))},addEventListener("message",(e=>{const n=e.data?.[f];if(W(n)){const[e,r]=n;t.set(r,e)}}))}}\n/*! (c) Andrea Giammarchi - ISC */const{Int32Array:J,Map:z,Uint16Array:q}=globalThis,{BYTES_PER_ELEMENT:G}=J,{BYTES_PER_ELEMENT:K}=q,Y=new WeakSet,X=new WeakMap,V={value:{then:e=>e()}};let Z=0;const Q=(e,{parse:t=JSON.parse,stringify:n=JSON.stringify,transform:r,interrupt:s}=JSON)=>{if(!X.has(e)){const o=U||e.postMessage,a=(t,...n)=>o.call(e,{[f]:n},{transfer:t}),i=typeof s===y?s:s?.handler,c=s?.delay||42,l=new TextDecoder("utf-16"),p=(e,t)=>e?B(t,0):(i?((e,t,n)=>{for(;"timed-out"===L(e,0,0,t);)n()})(t,c,i):L(t,0),V);let u=!1;X.set(e,new Proxy(new z,{[O]:(e,t)=>"string"==typeof t&&!t.startsWith("_"),[A]:(n,s)=>"then"===s?null:(...n)=>{const o=Z++;let i=new J(new H(2*G)),c=[];Y.has(n.at(-1)||c)&&Y.delete(c=n.pop()),a(c,o,i,s,r?n.map(r):n);const f=e!==globalThis;let d=0;return u&&f&&(d=setTimeout(console.warn,1e3,`πŸ’€πŸ”’ - Possible deadlock if proxy.${s}(...args) is awaited`)),p(f,i).value.then((()=>{clearTimeout(d);const e=i[1];if(!e)return;const n=K*e;return i=new J(new H(n+n%G)),a([],o,i),p(f,i).value.then((()=>t(l.decode(new q(i.buffer).slice(0,e)))))}))},[M](t,s,o){const a=typeof o;if(a!==y)throw new Error(`Unable to assign ${s} as ${a}`);if(!t.size){const s=new z;e.addEventListener("message",(async e=>{const o=e.data?.[f];if(W(o)){e.stopImmediatePropagation();const[a,i,...c]=o;let l;if(c.length){const[e,o]=c;if(t.has(e)){u=!0;try{const c=await t.get(e)(...o);if(void 0!==c){const e=n(r?r(c):c);s.set(a,e),i[1]=e.length}}catch(e){l=e}finally{u=!1}}else l=new Error(`Unsupported action: ${e}`);i[0]=1}else{const e=s.get(a);s.delete(a);for(let t=new q(i.buffer),n=0;n(Y.add(e),e);const{isArray:ee}=Array,te=(e,t)=>t,ne=e=>typeof e===y?(e=>e())(e):e;function re(){return this}const se=(e,t)=>e===g?[t]:{t:e,v:t},oe=(e,t=te)=>{let n=typeof e,r=e;return n===_&&(ee(e)?(n=g,r=e.at(0)):({t:n,v:r}=e)),t(n,r)},ae=(e,t)=>e===y?t:se(e,t),ie=(e,t=ae)=>{const n=null===e?w:typeof e;return t(n===_&&ee(e)?g:n,e)},ce=new FinalizationRegistry((([e,t,n])=>{n&&console.debug(`Held value ${String(t)} not relevant anymore`),e(t)})),le=Object.create(null),pe=(e,t,{debug:n,handler:r,return:s,token:o=e}=le)=>{const a=s||new Proxy(e,r||le),i=[a,[t,e,!!n]];return!1!==o&&i.push(o),ce.register(...i),a},{defineProperty:ue,deleteProperty:fe,getOwnPropertyDescriptor:de,getPrototypeOf:he,isExtensible:ge,ownKeys:ye,preventExtensions:we,set:me,setPrototypeOf:_e}=Reflect,{assign:be,create:Ee}=Object,ve=he(Int8Array),ke=(e,t)=>{const{get:n,set:r,value:s}=e;return n&&(e.get=t(n)),r&&(e.set=t(r)),s&&(e.value=t(s)),e},xe=e=>t=>ie(t,((t,n)=>{switch(t){case w:return se(w,n);case _:if(n===globalThis)return se(t,null);case g:case y:return e(t,n);case"boolean":case m:case b:case v:case"bigint":return se(t,n);case E:{if(Te.has(n))return se(t,Te.get(n));let e=Symbol.keyFor(n);if(e)return se(t,`.${e}`)}}throw new TypeError(`Unable to handle this ${t}: ${String(n)}`)})),Te=new Map(ye(Symbol).filter((e=>typeof Symbol[e]===E)).map((e=>[Symbol[e],e]))),Se=e=>{if(e.startsWith("."))return Symbol.for(e.slice(1));for(const[t,n]of Te)if(n===e)return t},Ae=e=>e;var je=((e,t)=>{const n=new WeakMap;{const{addEventListener:e}=EventTarget.prototype;ue(EventTarget.prototype,"addEventListener",{value(t,r,...s){return s.at(0)?.invoke&&(n.has(this)||n.set(this,new Map),n.get(this).set(t,[].concat(s[0].invoke)),delete s[0].invoke),e.call(this,t,r,...s)}})}return function(t,r,s,...o){let a=0,i=this?.transform||Ae;const c=new Map,l=new Map,{[s]:p}=t,u=o.length?be(Ee(globalThis),...o):globalThis,f=xe(((e,t)=>{if(!c.has(t)){let n;for(;l.has(n=a++););c.set(t,n),l.set(n,e===y?t:i(t))}return se(e,c.get(t))})),d=e=>{p(F,se(b,e))},h=(e,t)=>{switch(e){case _:if(null==t)return u;case g:if(typeof t===m)return l.get(t);if(!(t instanceof ve))for(const e in t)t[e]=w(t[e]);return t;case y:if(typeof t===b){const e=l.get(t)?.deref();if(e)return e;const r=function(...e){return e.at(0)instanceof Event&&(e=>{const{currentTarget:t,target:r,type:s}=e;for(const o of n.get(t||r)?.get(s)||[])e[o]()})(...e),p(k,se(y,t),f(this),e.map(f))};return l.set(t,new WeakRef(r)),pe(t,d,{return:r,token:!1})}return l.get(t);case E:return Se(t)}return t},w=e=>oe(e,h),W={[k]:(e,t,n)=>f(e.apply(t,n)),[x]:(e,t)=>f(new e(...t)),[T]:(e,t,n)=>f(ue(e,t,n)),[S]:(e,t)=>f(fe(e,t)),[R]:e=>f(he(e)),[A]:(e,t)=>f(e[t]),[j]:(e,t)=>{const n=de(e,t);return n?se(_,ke(n,f)):se(v,n)},[O]:(e,t)=>f(t in e),[P]:e=>f(ge(e)),[$]:e=>se(g,ye(e).map(f)),[N]:e=>f(we(e)),[M]:(e,t,n)=>f(me(e,t,n)),[I]:(e,t)=>f(_e(e,t)),[F](e){c.delete(l.get(e)),l.delete(e)}};return t[r]=(e,t,...n)=>{switch(e){case k:n[0]=w(n[0]),n[1]=n[1].map(w);break;case x:n[0]=n[0].map(w);break;case T:{const[e,t]=n;n[0]=w(e);const{get:r,set:s,value:o}=t;r&&(t.get=w(r)),s&&(t.set=w(s)),o&&(t.value=w(o));break}default:n=n.map(w)}return W[e](w(t),...n)},{proxy:t,[e.toLowerCase()]:u,[`is${e}Proxy`]:()=>!1}}})("Window"),Re=(e=>{let t=0;const n=new Map,r=new Map,s=Symbol();return function(o,a,i){const c=this?.transform||Ae,{[a]:l}=o,p=new Map,u=e=>{p.delete(e),l(F,f(e))},f=xe(((e,o)=>{if(s in o)return ne(o[s]);if(e===y){if(o=c(o),!r.has(o)){let e;for(;r.has(e=String(t++)););n.set(o,e),r.set(e,o)}return se(e,n.get(o))}if(!(o instanceof ve)){o=c(o);for(const e in o)o[e]=f(o[e])}return se(e,o)})),d=(e,t,n)=>{const r=p.get(n)?.deref();if(r)return r;const s=t===y?(e=>re.bind(e))(e):e,o=new Proxy(s,v);return p.set(n,new WeakRef(o)),pe(n,u,{return:o,token:!1})},h=e=>oe(e,((t,n)=>{switch(t){case _:if(null===n)return globalThis;case g:return typeof n===m?d(e,t,n):n;case y:return typeof n===b?r.get(n):d(e,t,n);case E:return Se(n)}return n})),w=(e,t,...n)=>h(l(e,ne(t),...n)),v={[k]:(e,t,n)=>w(k,e,f(t),n.map(f)),[x]:(e,t)=>w(x,e,t.map(f)),[T]:(e,t,n)=>{const{get:r,set:s,value:o}=n;return typeof r===y&&(n.get=f(r)),typeof s===y&&(n.set=f(s)),typeof o===y&&(n.value=f(o)),w(T,e,f(t),n)},[S]:(e,t)=>w(S,e,f(t)),[R]:e=>w(R,e),[A]:(e,t)=>t===s?e:w(A,e,f(t)),[j]:(e,t)=>{const n=w(j,e,f(t));return n&&ke(n,h)},[O]:(e,t)=>t===s||w(O,e,f(t)),[P]:e=>w(P,e),[$]:e=>w($,e).map(h),[N]:e=>w(N,e),[M]:(e,t,n)=>w(M,e,f(t),f(n)),[I]:(e,t)=>w(I,e,f(t))};o[i]=(e,t,s,o)=>{switch(e){case k:return h(t).apply(h(s),o.map(h));case F:{const e=h(t);n.delete(r.get(e)),r.delete(e)}}};const W=new Proxy(se(_,null),v);return{[e.toLowerCase()]:W,[`is${e}Proxy`]:e=>typeof e===_&&!!e&&s in e,proxy:o}}})("Window"),Oe=typeof Worker===y?Worker:class{};const Pe=new WeakMap,$e=(e,...t)=>{const n=Q(e,...t);if(!Pe.has(n)){const r=e instanceof Oe?je:Re;Pe.set(n,r.call(t.at(0),n,d,h))}return Pe.get(n)};$e.transfer=Q.transfer;const Ne={object(...e){return this.string(function(e){for(var t=e[0],n=1,r=arguments.length;n{const t=e||console,n={buffered:We,stderr:(t.stderr||console.error).bind(t),stdout:(t.stdout||console.log).bind(t)};return{stderr:(...e)=>n.stderr(...e),stdout:(...e)=>n.stdout(...e),async get(e){const t=await e;return Me.set(t,n),t}}},Fe=new TextDecoder,We=(e,t=10)=>{const n=[];return r=>{if(r instanceof Uint8Array)for(const s of r)s===t?e(Fe.decode(new Uint8Array(n.splice(0)))):n.push(s);else e(r)}},He=(e,...t)=>Ne[typeof e](e,...t),{isArray:De}=Array,{assign:Ce,create:Le,defineProperties:Be,defineProperty:Ue,entries:Je}=Object,{all:ze,resolve:qe}=new Proxy(Promise,{get:(e,t)=>e[t].bind(e)}),Ge=(e,t=location.href)=>new URL(e,t.replace(/^blob:/,"")).href,Ke=(e,t,n,r=!1,s=CustomEvent)=>{e.dispatchEvent(new s(`${t}:${n}`,{bubbles:!0,detail:{worker:r}}))},Ye=e=>Function(`\'use strict\';return (${e})`)(),Xe=e=>e.replace(/^(?:\\n|\\r\\n)/,""),Ve=Symbol.for("polyscript.js_modules"),Ze=new Map;Ue(globalThis,Ve,{value:Ze}),new Proxy(Ze,{get:(e,t)=>e.get(t),has:(e,t)=>e.has(t),ownKeys:e=>[...e.keys()]});const Qe=(e,t)=>!t.startsWith("_"),et=(e,t)=>new Proxy(e,{has:Qe,get:(e,n)=>e[t][n]}),tt=(e,t)=>import(e).then((e=>{Ze.set(t,{...e})})),nt=e=>new Promise(((t,n)=>{document.querySelector(`link[href="${e}"]`)&&t(),document.head.append(Ce(document.createElement("link"),{rel:"stylesheet",href:e,onload:t,onerror:n}))})),rt=e=>/\\.css/i.test(new URL(e).pathname),st=(e,t)=>e.has(t),ot=e=>[...e.keys()];var at=(e,t,n,r)=>{const s=globalThis[Ve];if(n)for(let[e,t]of Je(n)){let n=s.get(t);n&&!De(n)||(s.set(t,n||(n=[])),n.push(e))}return((e,t,n,r)=>new Proxy(e,{has:st,ownKeys:ot,get:(e,s)=>{let o=e.get(s);if(De(o)){let a=o;o=null;for(let e of a)e=Ge(e,r),rt(e)?n.importCSS(e):(n.importJS(e,s),o=t[Ve].get(s));e.set(s,o)}return o}}))(s,e,t,r)};const it=Object.getOwnPropertyDescriptors(Response.prototype),ct=e=>"function"==typeof e,lt={get:(e,t)=>it.hasOwnProperty(t)?((e,t,{get:n,value:r})=>n||!ct(r)?e.then((e=>e[t])):(...n)=>e.then((e=>e[t](...n))))(e,t,it[t]):((e,t)=>ct(t)?t.bind(e):t)(e,e[t])};var pt=(e,...t)=>new Proxy(fetch(e,...t),lt);Promise.withResolvers||(Promise.withResolvers=function(){var e,t,n=new this((function(n,r){e=n,t=r}));return{resolve:e,reject:t,promise:n}});const ut=!globalThis.window,ft=({FS:e,PATH:t,PATH_FS:n},r,s)=>{const o=n.resolve(r),a=t.dirname(o);return e.mkdirTree?e.mkdirTree(a):ht(e,a),e.writeFile(o,new Uint8Array(s),{canOwn:!0})},dt=e=>{const t=e.split("/");return t.pop(),t.join("/")},ht=(e,t)=>{const n=[];for(const r of t.split("/"))"."!==r&&".."!==r&&(n.push(r),r&&e.mkdir(n.join("/")))},gt=(e,t)=>{const n=[];for(const e of t.split("/"))switch(e){case"":case".":break;case"..":n.pop();break;default:n.push(e)}return[e.cwd()].concat(n).join("/").replace(/^\\/+/,"/")},yt=e=>{const t=e.map((e=>e.trim().replace(/(^[/]*|[/]*$)/g,""))).filter((e=>""!==e&&"."!==e)).join("/");return e[0].startsWith("/")?`/${t}`:t},wt=(e,t)=>pt(Ge(e,t)).arrayBuffer(),mt=(e,t,n,r)=>ze((e=>{for(const{files:t,to_file:n,from:r=""}of e){if(void 0!==t&&void 0!==n)throw new Error("Cannot use \'to_file\' and \'files\' parameters together!");if(void 0===t&&void 0===n&&r.endsWith("/"))throw new Error(`Couldn\'t determine the filename from the path ${r}, please supply \'to_file\' parameter.`)}return e.flatMap((({from:e="",to_folder:t=".",to_file:n,files:r})=>{if(De(r))return r.map((n=>({url:yt([e,n]),path:yt([t,n])})));const s=n||e.slice(1+e.lastIndexOf("/"));return[{url:e,path:yt([t,s])}]}))})(n).map((({url:n,path:s})=>wt(n,r).then((n=>e.writeFile(t,s,n)))))),_t=(e,t)=>t.endsWith("/")?`${t}${e.split("/").pop()}`:t,bt=(e,t)=>e.replace(/\\{.+?\\}/g,(e=>{if(!t.has(e))throw new SyntaxError(`Invalid template: ${e}`);return t.get(e)})),Et=(e,t,n,r)=>ze((e=>{const t=new Map,n=new Set,r=[];for(const[s,o]of Je(e))if(/^\\{.+\\}$/.test(s)){if(t.has(s))throw new SyntaxError(`Duplicated template: ${s}`);t.set(s,bt(o,t))}else{const e=bt(s,t),a=_t(e,bt(o||"./",t));if(n.has(a))throw new SyntaxError(`Duplicated destination: ${a}`);n.add(a),r.push({url:e,path:a})}return r})(n).map((({url:n,path:s})=>wt(n,r).then((r=>e.writeFile(t,s,r,n)))))),vt=({main:e,worker:t},n)=>{const r=[];if(t&&ut)for(let[e,s]of Je(t))e=Ge(e,n),r.push(tt(e,s));if(e&&!ut)for(let[t,s]of Je(e))t=Ge(t,n),rt(t)?nt(t):r.push(tt(t,s));return ze(r)},kt=new WeakMap,xt=(e,t,n)=>{"polyscript"===t&&(n.lazy_py_modules=async(...t)=>(await kt.get(e)(t),t.map((t=>e.pyimport(t))))),e.registerJsModule(t,n)},Tt=(e,t)=>{if(e.endsWith("/*")){if(/\\.(zip|whl|tgz|tar(?:\\.gz)?)$/.test(t))return RegExp.$1;throw new Error(`Unsupported archive ${t}`)}return""},St=(e,t,...n)=>{try{return e.runPython(He(t),...n)}catch(t){Me.get(e).stderr(t)}},At=async(e,t,...n)=>{try{return await e.runPythonAsync(He(t),...n)}catch(t){Me.get(e).stderr(t)}},jt=async(e,t,n)=>{const[r,...s]=t.split(".");let o,a=e.globals.get(r);for(const e of s)[o,a]=[a,a[e]];try{await a.call(o,n)}catch(t){Me.get(e).stderr(t)}};var Rt=(new TextEncoder).encode(\'from uio import StringIO\\nimport sys\\n\\nclass Response:\\n def __init__(self, f):\\n self.raw = f\\n self.encoding = "utf-8"\\n self._cached = None\\n\\n def close(self):\\n if self.raw:\\n self.raw.close()\\n self.raw = None\\n self._cached = None\\n\\n @property\\n def content(self):\\n if self._cached is None:\\n try:\\n self._cached = self.raw.read()\\n finally:\\n self.raw.close()\\n self.raw = None\\n return self._cached\\n\\n @property\\n def text(self):\\n return str(self.content, self.encoding)\\n\\n def json(self):\\n import ujson\\n\\n return ujson.loads(self.content)\\n\\n\\n# TODO try to support streaming xhr requests, a-la pyodide-http\\nHEADERS_TO_IGNORE = ("user-agent",)\\n\\n\\ntry:\\n import js\\nexcept Exception as err:\\n raise OSError("This version of urequests can only be used in the browser")\\n\\n# TODO try to support streaming xhr requests, a-la pyodide-http\\n\\nHEADERS_TO_IGNORE = ("user-agent",)\\n\\n\\ndef request(\\n method,\\n url,\\n data=None,\\n json=None,\\n headers={},\\n stream=None,\\n auth=None,\\n timeout=None,\\n parse_headers=True,\\n):\\n from js import XMLHttpRequest\\n\\n xhr = XMLHttpRequest.new()\\n xhr.withCredentials = False\\n\\n if auth is not None:\\n import ubinascii\\n\\n username, password = auth\\n xhr.open(method, url, False, username, password)\\n else:\\n xhr.open(method, url, False)\\n\\n for name, value in headers.items():\\n if name.lower() not in HEADERS_TO_IGNORE:\\n xhr.setRequestHeader(name, value)\\n\\n if timeout:\\n xhr.timeout = int(timeout * 1000)\\n\\n if json is not None:\\n assert data is None\\n import ujson\\n\\n data = ujson.dumps(json)\\n # s.write(b"Content-Type: application/json\\\\r\\\\n")\\n xhr.setRequestHeader("Content-Type", "application/json")\\n\\n xhr.send(data)\\n\\n # Emulates the construction process in the original urequests\\n resp = Response(StringIO(xhr.responseText))\\n resp.status_code = xhr.status\\n resp.reason = xhr.statusText\\n resp.headers = xhr.getAllResponseHeaders()\\n\\n return resp\\n\\n\\n# Other methods - head, post, put, patch, delete - are not used by\\n# mip and therefore not included\\n\\n\\ndef get(url, **kw):\\n return request("GET", url, **kw)\\n\\n\\n# Content below this line is from the Micropython MIP package and is covered\\n# by the applicable MIT license:\\n# \\n# THE SOFTWARE IS PROVIDED β€œAS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, \\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER \\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING \\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER \\n# DEALINGS IN THE SOFTWARE.\\n\\n# MicroPython package installer\\n# MIT license; Copyright (c) 2022 Jim Mussared\\n\\n\\n_PACKAGE_INDEX = const("https://micropython.org/pi/v2")\\n_CHUNK_SIZE = 128\\n\\n\\n# This implements os.makedirs(os.dirname(path))\\ndef _ensure_path_exists(path):\\n import os\\n\\n split = path.split("/")\\n\\n # Handle paths starting with "/".\\n if not split[0]:\\n split.pop(0)\\n split[0] = "/" + split[0]\\n\\n prefix = ""\\n for i in range(len(split) - 1):\\n prefix += split[i]\\n try:\\n os.stat(prefix)\\n except:\\n os.mkdir(prefix)\\n prefix += "/"\\n\\n\\n# Copy from src (stream) to dest (function-taking-bytes)\\ndef _chunk(src, dest):\\n buf = memoryview(bytearray(_CHUNK_SIZE))\\n while True:\\n n = src.readinto(buf)\\n if n == 0:\\n break\\n dest(buf if n == _CHUNK_SIZE else buf[:n])\\n\\n\\n# Check if the specified path exists and matches the hash.\\ndef _check_exists(path, short_hash):\\n import os\\n\\n try:\\n import binascii\\n import hashlib\\n\\n with open(path, "rb") as f:\\n hs256 = hashlib.sha256()\\n _chunk(f, hs256.update)\\n existing_hash = str(binascii.hexlify(hs256.digest())[: len(short_hash)], "utf-8")\\n return existing_hash == short_hash\\n except:\\n return False\\n\\n\\ndef _rewrite_url(url, branch=None):\\n if not branch:\\n branch = "HEAD"\\n if url.startswith("github:"):\\n url = url[7:].split("/")\\n url = (\\n "https://raw.githubusercontent.com/"\\n + url[0]\\n + "/"\\n + url[1]\\n + "/"\\n + branch\\n + "/"\\n + "/".join(url[2:])\\n )\\n return url\\n\\n\\ndef _download_file(url, dest):\\n response = get(url)\\n try:\\n if response.status_code != 200:\\n print("Error", response.status_code, "requesting", url)\\n return False\\n\\n print("Copying:", dest)\\n _ensure_path_exists(dest)\\n with open(dest, "wb") as f:\\n _chunk(response.raw, f.write)\\n\\n return True\\n finally:\\n response.close()\\n\\n\\ndef _install_json(package_json_url, index, target, version, mpy):\\n response = get(_rewrite_url(package_json_url, version))\\n try:\\n if response.status_code != 200:\\n print("Package not found:", package_json_url)\\n return False\\n\\n package_json = response.json()\\n finally:\\n response.close()\\n for target_path, short_hash in package_json.get("hashes", ()):\\n fs_target_path = target + "/" + target_path\\n if _check_exists(fs_target_path, short_hash):\\n print("Exists:", fs_target_path)\\n else:\\n file_url = "{}/file/{}/{}".format(index, short_hash[:2], short_hash)\\n if not _download_file(file_url, fs_target_path):\\n print("File not found: {} {}".format(target_path, short_hash))\\n return False\\n for target_path, url in package_json.get("urls", ()):\\n fs_target_path = target + "/" + target_path\\n if not _download_file(_rewrite_url(url, version), fs_target_path):\\n print("File not found: {} {}".format(target_path, url))\\n return False\\n for dep, dep_version in package_json.get("deps", ()):\\n if not _install_package(dep, index, target, dep_version, mpy):\\n return False\\n return True\\n\\n\\ndef _install_package(package, index, target, version, mpy):\\n if (\\n package.startswith("http://")\\n or package.startswith("https://")\\n or package.startswith("github:")\\n ):\\n if package.endswith(".py") or package.endswith(".mpy"):\\n print("Downloading {} to {}".format(package, target))\\n return _download_file(\\n _rewrite_url(package, version), target + "/" + package.rsplit("/")[-1]\\n )\\n else:\\n if not package.endswith(".json"):\\n if not package.endswith("/"):\\n package += "/"\\n package += "package.json"\\n print("Installing {} to {}".format(package, target))\\n else:\\n if not version:\\n version = "latest"\\n print("Installing {} ({}) from {} to {}".format(package, version, index, target))\\n\\n mpy_version = (\\n sys.implementation._mpy & 0xFF if mpy and hasattr(sys.implementation, "_mpy") else "py"\\n )\\n\\n # WARNING: mpy_version fails miserably with 1.22.0-380\\n package = "{}/package/{}/{}/{}.json".format(index, "py", package, version)\\n\\n return _install_json(package, index, target, version, mpy)\\n\\n\\ndef install(package, index=None, target=None, version=None, mpy=True):\\n if not target:\\n for p in sys.path:\\n if p.endswith("/lib"):\\n target = p\\n break\\n else:\\n print("Unable to find lib dir in sys.path")\\n return\\n\\n if not index:\\n index = _PACKAGE_INDEX\\n\\n if _install_package(package, index.rstrip("/"), target, version, mpy):\\n print("Done")\\n else:\\n print("Package may be partially installed")\\n\');const Ot=async e=>(await import("./toml-DiUM0_qs.js")).parse(e),Pt=(e,t)=>{try{e.mkdir(t)}catch(e){}};var $t={type:"micropython",module:(e="1.23.0")=>`https://cdn.jsdelivr.net/npm/@micropython/micropython-webassembly-pyscript@${e}/micropython.mjs`,async engine({loadMicroPython:e},t,n,r){const{stderr:s,stdout:o,get:a}=Ie({stderr:We(console.error),stdout:We(console.log)});n=n.replace(/\\.m?js$/,".wasm");const i=await a(e({linebuffer:!1,stderr:s,stdout:o,url:n})),c=Nt.bind(this,i,r);return kt.set(i,c),t.files&&await Et(this,i,t.files,r),t.fetch&&await mt(this,i,t.fetch,r),t.js_modules&&await vt(t.js_modules,r),this.writeFile(i,"./mip.py",Rt),t.packages&&await c(t.packages),i},registerJSModule:xt,run:St,runAsync:At,runEvent:jt,transform:(e,t)=>e.PyProxy.toJs(t),writeFile:(e,t,n,r)=>{const{FS:s,_module:{PATH:o,PATH_FS:a}}=e,i={FS:s,PATH:o,PATH_FS:a},c=Tt(t,r);if(c){const r=t.slice(0,-1);switch("./"!==r&&s.mkdir(r),c){case"whl":case"zip":{const e=new Blob([n],{type:"application/zip"});return import("./zip-BxogYCy6.js").then((async({BlobReader:t,Uint8ArrayWriter:n,ZipReader:a})=>{const i=new a(new t(e));for(const e of await i.getEntries()){const{directory:t,filename:a}=e,i=r+a;if(t)Pt(s,i);else{Pt(s,o.dirname(i));const t=await e.getData(new n);s.writeFile(i,t,{canOwn:!0})}}i.close()}))}case"tgz":case"tar.gz":{const t="./_.tar.gz";return ft(i,t,n),void e.runPython(`\\n import os, gzip, tarfile\\n tar = tarfile.TarFile(fileobj=gzip.GzipFile(fileobj=open("${t}", "rb")))\\n for f in tar:\\n name = f"${r}{f.name}"\\n if f.type == tarfile.DIRTYPE:\\n if f.name != "./":\\n os.mkdir(name.strip("/"))\\n else:\\n dir = os.path.dirname(name)\\n if not os.path.exists(dir):\\n os.mkdir(dir)\\n source = tar.extractfile(f)\\n with open(name, "wb") as dest:\\n dest.write(source.read())\\n dest.close()\\n tar.close()\\n os.remove("${t}")\\n `)}}}return ft(i,t,n)}};async function Nt(e,t,n){let r;for(const s of n)if(s.endsWith(".whl")){const n=Ge(s,t),r=await pt(n).arrayBuffer();await this.writeFile(e,"./*",r,n)}else r||(r=e.pyimport("mip")),r.install(s)}const Mt={dict_converter:Object.fromEntries};let It=!1;const Ft=e=>(...t)=>{try{return It=!0,e(...t)}finally{It=!1}};let Wt=!1;const Ht=()=>{if(Wt)return;Wt=!0;const e=new WeakMap,t=e=>e.destroy(),n=n=>{for(let r=0;r`https://cdn.jsdelivr.net/pyodide/v${e}/full/pyodide.mjs`,async engine({loadPyodide:e},t,n,r){ut||"auto"!==t.experimental_create_proxy||Ht();const{stderr:s,stdout:o,get:a}=Ie(),i=n.slice(0,n.lastIndexOf("/")),c=await a(e({stderr:s,stdout:o,indexURL:i})),l=Ct.bind(c);return kt.set(c,l),t.files&&await Et(this,c,t.files,r),t.fetch&&await mt(this,c,t.fetch,r),t.js_modules&&await vt(t.js_modules,r),t.packages&&await l(t.packages),c},registerJSModule:xt,run:Ft(St),runAsync:Ft(At),runEvent:Ft(jt),transform:({ffi:{PyProxy:e}},t)=>t instanceof e?t.toJs(Mt):t,writeFile:(e,t,n,r)=>{const s=Tt(t,r);if(s)return e.unpackArchive(n,s,{extractDir:t.slice(0,-1)});const{FS:o,PATH:a,_module:{PATH_FS:i}}=e;return ft({FS:o,PATH:a,PATH_FS:i},t,n)}};async function Ct(e){await this.loadPackage("micropip");const t=this.pyimport("micropip");await t.install(e,{keep_going:!0}),t.destroy()}const Lt="ruby-wasm-wasi",Bt=Lt.replace(/\\W+/g,"_");var Ut={type:Lt,experimental:!0,module:(e="2.6.1")=>`https://cdn.jsdelivr.net/npm/@ruby/3.2-wasm-wasi@${e}/dist/browser/+esm`,async engine({DefaultRubyVM:e},t,n,r){n=n.replace(/\\/browser\\/\\+esm$/,"/ruby.wasm");const s=await pt(n).arrayBuffer(),o=await WebAssembly.compile(s),{vm:a}=await e(o);return t.files&&await Et(this,a,t.files,r),t.fetch&&await mt(this,a,t.fetch,r),t.js_modules&&await vt(t.js_modules,r),a},registerJSModule(e,t,n){t=t.replace(/\\W+/g,"__");const r=`__module_${Bt}_${t}`;globalThis[r]=n,this.run(e,`require "js";$${t}=JS.global[:${r}]`),delete globalThis[r]},run:(e,t,...n)=>e.eval(He(t),...n),runAsync:(e,t,...n)=>e.evalAsync(He(t),...n),async runEvent(e,t,n){if(/^xworker\\.(on\\w+)$/.test(t)){const{$1:t}=RegExp,r=`__module_${Bt}_event`;globalThis[r]=n,this.run(e,`require "js";$xworker.call("${t}",JS.global[:${r}])`),delete globalThis[r]}else{const r=this.run(e,`method(:${t})`);await r.call(t,e.wrap(n))}},transform:(e,t)=>t,writeFile:()=>{throw new Error(`writeFile is not supported in ${Lt}`)}};var Jt={type:"wasmoon",module:(e="1.16.0")=>`https://cdn.jsdelivr.net/npm/wasmoon@${e}/+esm`,async engine({LuaFactory:e,LuaLibraries:t},n,r,s){const{stderr:o,stdout:a,get:i}=Ie(),c=await i((new e).createEngine());return c.global.getTable(t.Base,(e=>{c.global.setField(e,"print",a),c.global.setField(e,"printErr",o)})),n.files&&await Et(this,c,n.files,s),n.fetch&&await mt(this,c,n.fetch,s),n.js_modules&&await vt(n.js_modules,s),c},registerJSModule:(e,t,n)=>{e.global.set(t,n)},run:(e,t,...n)=>{try{return e.doStringSync(He(t),...n)}catch(t){Me.get(e).stderr(t)}},runAsync:async(e,t,...n)=>{try{return await e.doString(He(t),...n)}catch(t){Me.get(e).stderr(t)}},runEvent:async(e,t,n)=>{const[r,...s]=t.split(".");let o,a=e.global.get(r);for(const e of s)[o,a]=[a,a[e]];try{await a.call(o,n)}catch(t){Me.get(e).stderr(t)}},transform:(e,t)=>t,writeFile:({cmodule:{module:{FS:e}}},t,n)=>((e,t,n)=>(ht(e,dt(t)),t=gt(e,t),e.writeFile(t,new Uint8Array(n),{canOwn:!0})))(e,t,n)};const zt=new WeakMap,qt=async(e,t)=>{const{shelter:n,destroy:r,io:s}=zt.get(e),{output:o,result:a}=await n.captureR(He(t));for(const{type:e,data:t}of o)s[e](t);return pe(a,r,{token:!1})};var Gt={type:"webr",experimental:!0,module:(e="0.3.3")=>`https://cdn.jsdelivr.net/npm/webr@${e}/dist/webr.mjs`,async engine(e,t,n,r){const{get:s}=Ie(),o=new e.WebR;await s(o.init().then((()=>o)));const a=await new o.Shelter;return zt.set(o,{module:e,shelter:a,destroy:a.destroy.bind(a),io:Me.get(o)}),t.files&&await Et(this,o,t.files,r),t.fetch&&await mt(this,o,t.fetch,r),t.js_modules&&await vt(t.js_modules,r),o},registerJSModule(e,t){console.warn(`Experimental interpreter: module ${t} is not supported (yet)`)},run:qt,runAsync:qt,async runEvent(e,t,n){await e.evalRVoid(`${t}(event)`,{env:{event:{type:[n.type]}}})},transform:(e,t)=>(console.log("transforming",t),t),writeFile:()=>{}};const Kt=new Map,Yt=new Map,Xt=new Proxy(new Map,{get(e,t){if(!e.has(t)){const[n,...r]=t.split("@"),s=Kt.get(n),o=/^(?:\\.?\\.?\\/|https?:\\/\\/)/i.test(r)?r.join("@"):s.module(...r);e.set(t,{url:o,module:import(o),engine:s.engine.bind(s)})}const{url:n,module:r,engine:s}=e.get(t);return(e,o)=>r.then((r=>(Yt.set(t,e),s(r,e,n,o))))}}),Vt=e=>{for(const t of[].concat(e.type))Kt.set(t,e)};for(const e of[$t,Dt,Ut,Jt,Gt])Vt(e);const{parse:Zt}=JSON,Qt=e=>{try{return Zt(e)}catch(t){return Ot(e)}},en=(e,t,n,r={})=>{if(t){const[e,s]=((e,t="./config.txt")=>{let n=typeof e;return"string"===n&&/\\.(json|toml|txt)$/.test(e)?n=RegExp.$1:e=t,[Ge(e),n]})(t,n);"json"===s?r=pt(e).json():"toml"===s?r=pt(e).text().then(Ot):"string"===s?r=Qt(t):"object"===s&&t?r=t:"txt"===s&&"string"==typeof r&&(r=Qt(r)),t=e}return qe(r).then((n=>Xt[e](n,t)))},tn="BeforeRun",nn="AfterRun",rn=[`code${tn}`,`code${tn}Async`,`code${nn}`,`code${nn}Async`],sn=["onWorker","onReady",`on${tn}`,`on${tn}Async`,`on${nn}`,`on${nn}Async`];function on(e,t){const{run:n,runAsync:r}=Kt.get(this.type);return{...e,run:n.bind(this,t),runAsync:r.bind(this,t)}}const an=(e,t,n,r,s,o)=>{if(s||o){const a=on.bind(e,t),i=r?"runAsync":"run",c=e[i];e[i]=r?async function(e,t,...r){s&&await s.call(this,a(e),n);const i=await c.call(this,e,t,...r);return o&&await o.call(this,a(e),n),i}:function(e,t,...r){s&&s.call(this,a(e),n);const i=c.call(this,e,t,...r);return o&&o.call(this,a(e),n),i}}};let cn,ln,pn;const un=(e,t)=>{addEventListener(e,t||(async t=>{try{await cn,ln(`xworker.on${e}`,t)}catch(e){postMessage(e)}}),!!t&&{once:!0})},{parse:fn,stringify:dn}=u,{proxy:hn,window:gn,isWindowProxy:yn}=$e(self,{parse:fn,stringify:dn,transform:e=>pn?pn(e):e}),wn={sync:hn,window:gn,isWindowProxy:yn,onmessage:console.info,onerror:console.error,onmessageerror:console.warn,postMessage:postMessage.bind(self)};un("message",(({data:{options:e,config:t,configURL:n,code:r,hooks:s}})=>{cn=(async()=>{try{const{id:o,tag:a,type:i,custom:c,version:l,config:p,async:u}=e,f=((e,t="")=>`${e}@${t}`.replace(/@$/,""))(i,l),d=await en(f,t,n,p),{js_modules:h,sync_main_only:g}=Yt.get(f),y=h?.main;let w=!g;try{new SharedArrayBuffer(4),w=!0}catch(e){if(w)throw new Error(["Unable to use SharedArrayBuffer due insecure environment.","Please read requirements in MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements"].join("\\n"))}const m=Le(Kt.get(i)),_=((e,t,n,r)=>({type:t,config:n,interpreter:r,io:Me.get(r),run:(t,...n)=>e.run(r,t,...n),runAsync:(t,...n)=>e.runAsync(r,t,...n),runEvent:(...t)=>e.runEvent(r,...t)}))(m,c||i,p||{},d);let b="run";if(u&&(b+="Async"),s){let e,t,n="",r="";for(const e of rn){const t=s[e];if(t){const s=e.endsWith("Async");(s&&u||!s&&!u)&&(e.startsWith("codeBefore")?n=t:r=t)}}(n||r)&&((e,t,n,r)=>{const s=e[t].bind(e);e[t]="run"===t?(e,t,...o)=>{n&&s(e,n,...o);const a=s(e,Xe(t),...o);return r&&s(e,r,...o),a}:async(e,t,...o)=>{n&&await s(e,n,...o);const a=await s(e,Xe(t),...o);return r&&await s(e,r,...o),a}})(m,b,n,r);for(const n of sn.slice(2)){const r=s[n];if(r){const s=n.endsWith("Async");if(s&&u||!s&&!u){const s=Ye(r);n.startsWith("onBefore")?e=s:t=s}}}an(m,_,wn,u,e,t)}let E,v,k,x=null,T="";w&&(({CustomEvent:E,document:v}=gn),x=o&&v.getElementById(o)||null,k=e=>Ke(x,c||i,e,!0,E));const S=at(gn,hn,y,t);return((e,t,n,r)=>{if("pyodide"===e)return;const s="polyscript.js_modules";for(const e of Reflect.ownKeys(r))t.registerJSModule(n,`${s}.${e}`,et(r,e));t.registerJSModule(n,s,r)})(i,m,d,S),m.registerJSModule(d,"polyscript",{xworker:wn,currentScript:x,config:_.config,js_modules:S,get target(){return!T&&x&&("SCRIPT"===a?x.after(Ce(v.createElement(`script-${c||i}`),{id:T=`${o}-target`})):(T=o,x.replaceChildren(),x.style.display="block")),T}}),ln=m.runEvent.bind(m,d),pn=m.transform.bind(m,d),x&&k("ready"),s?.onReady&&Ye(s?.onReady).call(m,on.call(m,_,d),wn),await m[b](d,r),x&&k("done"),postMessage("polyscript:done"),d}catch(e){postMessage(e)}})(),un("error"),un("message"),un("messageerror")}));\n'.replace(Le,Ce)],{type:"application/javascript"})),{type:"module"}),{postMessage:s}=r,a=this instanceof Tn;if(e.length){const[t,r]=e;(n=et({},n||{type:t,version:r})).type||(n.type=t)}const[i]=hn(n.config,n.configURL),c=o(t).text().then((e=>{const t=a?this.toJSON():void 0;s.call(r,{options:n,config:i,code:e,hooks:t})})),l=et(He(r,w).proxy,{importJS:_t,importCSS:vt}),p=Promise.withResolvers();return nt(r,{sync:{value:l},ready:{value:p.promise},postMessage:{value:(e,...t)=>c.then((()=>s.call(r,e,...t)))},onerror:{writable:!0,configurable:!0,value:console.error}}),r.addEventListener("message",(e=>{const{data:t}=e,n=t instanceof Error;(n||"polyscript:done"===t)&&(e.stopImmediatePropagation(),n?(p.reject(t),r.onerror(tt(e,{type:{value:"error"},error:{value:t}}))):p.resolve(r))})),a&&this.onWorker?.(this.interpreter,r),r};const An="Invalid content",On="Invalid worker attribute",Rn="Invalid worker attribute";var jn=e=>{const{src:t,worker:n}=e.attributes;if(n){let{value:r}=n;if(r)throw new SyntaxError(Rn);if(r=t?.value,!r){if(t)throw new SyntaxError(On);if(e.childElementCount){const{innerHTML:t,localName:n,type:s}=e,o=s||n.replace(/-script$/,"");r=Ze(t),console.warn(`Deprecated: use + + + + + + diff --git a/test/integration/micropython.js b/test/integration/micropython.js index 63576f63..5bae8ba6 100644 --- a/test/integration/micropython.js +++ b/test/integration/micropython.js @@ -52,4 +52,9 @@ module.exports = (playwright, baseURL) => { test('MicroPython local intepreter', python.localInterpreter(playwright, baseURL)); test('MicroPython mip', python.waitForDone(playwright, `${baseURL}/mip.html`)); + + test('MicroPython Storage', async ({ page }) => { + await page.goto(`${baseURL}/storage.html`); + await page.waitForSelector(`html.ready.main.worker`); + }); }; diff --git a/versions/micropython b/versions/micropython index a6c2798a..8d803471 100644 --- a/versions/micropython +++ b/versions/micropython @@ -1 +1 @@ -1.23.0 +1.24.0-preview-44