UNPKG

starboard-python

Version:
467 lines (459 loc) 112 kB
var css = "@font-face{font-family:PyodideIcons;src:url(\"data:application/x-font-ttf;charset=utf-8;base64,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\") format('truetype');font-weight:400;font-style:normal;font-display:block}.fa{font-family:PyodideIcons;font-style:normal;font-weight:400;font-variant:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-search-plus:before{content:\"\\f00e\"}.fa-home:before{content:\"\\f015\"}.fa-download:before{content:\"\\f019\"}.fa-arrows:before{content:\"\\f047\"}.fa-arrow-left:before{content:\"\\f060\"}.fa-arrow-right:before{content:\"\\f061\"}.rendered_html{overflow:auto;max-height:30em;color:#000}.rendered_html em{font-style:italic}.rendered_html strong{font-weight:700}.rendered_html :link,.rendered_html :visited,.rendered_html u{text-decoration:underline}.rendered_html h1{font-size:185.7%;margin:1.08em 0 0;font-weight:700;line-height:1}.rendered_html h2{font-size:157.1%;margin:1.27em 0 0;font-weight:700;line-height:1}.rendered_html h3{font-size:128.6%;margin:1.55em 0 0;font-weight:700;line-height:1}.rendered_html h4{font-size:100%;margin:2em 0 0;font-weight:700;line-height:1}.rendered_html h5,.rendered_html h6{font-size:100%;margin:2em 0 0;font-weight:700;line-height:1;font-style:italic}.rendered_html h1:first-child{margin-top:.538em}.rendered_html h2:first-child{margin-top:.636em}.rendered_html h3:first-child{margin-top:.777em}.rendered_html h4:first-child,.rendered_html h5:first-child,.rendered_html h6:first-child{margin-top:1em}.rendered_html ol:not(.list-inline),.rendered_html ul:not(.list-inline){padding-left:2em}.rendered_html ul{list-style:disc}.rendered_html ul ul{list-style:square;margin-top:0}.rendered_html ul ul ul{list-style:circle}.rendered_html ol{list-style:decimal}.rendered_html ol ol{list-style:upper-alpha;margin-top:0}.rendered_html ol ol ol{list-style:lower-alpha}.rendered_html ol ol ol ol{list-style:lower-roman}.rendered_html ol ol ol ol ol{list-style:decimal}.rendered_html *+ol,.rendered_html *+ul{margin-top:1em}.rendered_html hr{color:#000;background-color:#000}.rendered_html pre{margin:1em 2em;padding:0;background-color:#fff}.rendered_html code{background-color:#eff0f1}.rendered_html p code{padding:1px 5px}.rendered_html pre code{background-color:#fff}.rendered_html code,.rendered_html pre{border:0;color:#000;font-size:100%}.rendered_html blockquote{margin:1em 2em}.rendered_html table{margin-left:auto;margin-right:auto;border:none;border-collapse:collapse;border-spacing:0;color:#000;font-size:12px;table-layout:fixed}.rendered_html thead{border-bottom:1px solid #000;vertical-align:bottom}.rendered_html td,.rendered_html th,.rendered_html tr{text-align:right;vertical-align:middle;padding:.5em;line-height:normal;white-space:normal;max-width:none;border:none}.rendered_html th{font-weight:700}.rendered_html tbody tr:nth-child(odd){background:#f5f5f5}.rendered_html tbody tr:hover{background:rgba(66,165,245,.2)}.rendered_html *+table{margin-top:1em}.rendered_html p{text-align:left}.rendered_html *+p{margin-top:1em}.rendered_html img{display:block;margin-left:auto;margin-right:auto}.rendered_html *+img{margin-top:1em}.rendered_html img,.rendered_html svg{max-width:100%;height:auto}.rendered_html img.unconfined,.rendered_html svg.unconfined{max-width:none}.rendered_html .alert{margin-bottom:initial}.rendered_html *+.alert{margin-top:1em}[dir=rtl] .rendered_html p{text-align:right}"; // Global singleton let pluginOpts = {}; function getPluginOpts() { return pluginOpts; } function setPluginOpts(opts) { pluginOpts = opts; } /** * Overwrite present options */ function updatePluginOptions(opts) { pluginOpts = { ...pluginOpts, ...opts, }; } let nanoid = (size = 21) => { let id = ''; let bytes = crypto.getRandomValues(new Uint8Array(size)); while (size--) { let byte = bytes[size] & 63; if (byte < 36) { id += byte.toString(36); } else if (byte < 62) { id += (byte - 26).toString(36).toUpperCase(); } else if (byte < 63) { id += '_'; } else { id += '-'; } } return id }; function assertUnreachable(_x) { throw new Error("This case should have never been reached"); } /** * One-way memory, can block a web worker until data from the main thread arrives. * * Web Worker Usage: * 1. Lock "web worker" * 2. Set "shared memory signal" * 3. Notify main thread (Main thread does stuff) * 4. Wait for "shared memory signal" * 5. Read size buffer * 6. Read shared memory * 7. If the size buffer was bigger than the read memory size * 7.1. Set "shared memory signal" * 7.2. Notify main thread (Main thread writes remaining data to shared memory) * 7.3. Wait for "shared memory signal" * 7.4. Read shared memory * 7.5. Go back to step 7. (loop) * 8. Unlock "web worker" * * Main Thread Usage: * 1. Get notification * 2. Do operations * 3. Serialize data * 4. Write size into the size buffer * 5. Write partial data into shared memory * 6. Unlock "shared memory signal" (Worker does stuff) * 7. If not everything has been written to the shared memory yet * 7.1. Get notification * 7.2. Write partial data into shared memory * 7.3. Unlock "shared memory signal" (Worker does stuff) * 7.4. Go back to step 7. (loop) */ class AsyncMemory { constructor(sharedLock, sharedMemory) { this.sharedLock = sharedLock ?? new SharedArrayBuffer(8 * Int32Array.BYTES_PER_ELEMENT); this.lockAndSize = new Int32Array(this.sharedLock); if (this.lockAndSize.length < 8) { throw new Error("Expected an sharedLock with at least 8x32 bytes"); } this.sharedMemory = sharedMemory ?? new SharedArrayBuffer(1024); this.memory = new Uint8Array(this.sharedMemory); if (this.sharedMemory.byteLength < 1024) { throw new Error("Expected an sharedMemory with at least 1024 bytes"); } } /** * Should be called from the worker thread */ lockWorker() { const oldValue = Atomics.compareExchange(this.lockAndSize, AsyncMemory.LOCK_WORKER_INDEX, AsyncMemory.UNLOCKED, // old value AsyncMemory.LOCKED // new value ); if (oldValue !== AsyncMemory.UNLOCKED) { throw new Error(`Cannot lock worker, the worker has to be unlocked ${AsyncMemory.UNLOCKED} !== ${oldValue}`); } } /** * Should be called from the worker thread */ lockSize() { const oldValue = Atomics.compareExchange(this.lockAndSize, AsyncMemory.LOCK_SIZE_INDEX, AsyncMemory.UNLOCKED, // old value AsyncMemory.LOCKED // new value ); if (oldValue !== AsyncMemory.UNLOCKED) { throw new Error(`Cannot set size flag, the size has to be unlocked ${AsyncMemory.UNLOCKED} !== ${oldValue}`); } } /** * Only legal if the worker is locked */ waitForSize() { Atomics.wait(this.lockAndSize, AsyncMemory.LOCK_SIZE_INDEX, AsyncMemory.LOCKED); } /** * Should be called from the main thread! * Only legal if the worker is locked and the size is locked */ writeSize(value) { return Atomics.store(this.lockAndSize, AsyncMemory.SIZE_INDEX, value); } /** * Only legal if the worker is locked but the size is not */ readSize() { return Atomics.load(this.lockAndSize, AsyncMemory.SIZE_INDEX); } /** * Should be called from the main thread! */ unlockSize() { const oldValue = Atomics.compareExchange(this.lockAndSize, AsyncMemory.LOCK_SIZE_INDEX, AsyncMemory.LOCKED, // old value AsyncMemory.UNLOCKED // new value ); if (oldValue != AsyncMemory.LOCKED) { throw new Error("Tried to unlock, but was already unlocked"); } Atomics.notify(this.lockAndSize, AsyncMemory.LOCK_SIZE_INDEX); } /** * Ensures that the size gets unlocked */ forceUnlockSize() { const oldValue = Atomics.compareExchange(this.lockAndSize, AsyncMemory.LOCK_SIZE_INDEX, AsyncMemory.LOCKED, // old value AsyncMemory.UNLOCKED // new value ); if (oldValue != AsyncMemory.LOCKED) { // And force unlock it Atomics.store(this.lockAndSize, AsyncMemory.LOCK_SIZE_INDEX, AsyncMemory.UNLOCKED); } Atomics.notify(this.lockAndSize, AsyncMemory.LOCK_SIZE_INDEX); } /** * Should be called from the worker thread! */ unlockWorker() { const oldValue = Atomics.compareExchange(this.lockAndSize, AsyncMemory.LOCK_WORKER_INDEX, AsyncMemory.LOCKED, // old value AsyncMemory.UNLOCKED // new value ); if (oldValue != AsyncMemory.LOCKED) { throw new Error("Tried to unlock, but was already unlocked"); } Atomics.notify(this.lockAndSize, AsyncMemory.LOCK_WORKER_INDEX); } } // Reference: https://v8.dev/features/atomics AsyncMemory.LOCK_WORKER_INDEX = 0; AsyncMemory.LOCK_SIZE_INDEX = 2; AsyncMemory.SIZE_INDEX = 4; AsyncMemory.UNLOCKED = 0; AsyncMemory.LOCKED = 1; const SERIALIZATION = { UNDEFINED: 0, NULL: 1, FALSE: 2, TRUE: 3, NUMBER: 4, DATE: 5, KNOWN_SYMBOL: 6, STRING: 10, BIGINT: 11, OBJECT: 255, }; // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol const KNOWN_SYMBOLS = [ Symbol.asyncIterator, Symbol.hasInstance, Symbol.isConcatSpreadable, Symbol.iterator, Symbol.match, Symbol.matchAll, Symbol.replace, Symbol.search, Symbol.species, Symbol.split, Symbol.toPrimitive, Symbol.toStringTag, Symbol.unscopables, ]; const textEncoder = new TextEncoder(); new TextDecoder("utf-8"); const encodeFloat = useFloatEncoder(); function useFloatEncoder() { // https://stackoverflow.com/a/14379836/3492994 const temp = new ArrayBuffer(8); const tempFloat64 = new Float64Array(temp); const tempUint8 = new Uint8Array(temp); return function (value) { tempFloat64[0] = value; return tempUint8; }; } /** * Lets one other thread access the objects on this thread. * Usually runs on the main thread. */ class ObjectProxyHost { constructor(memory) { this.rootReferences = new Map(); this.temporaryReferences = new Map(); this.memory = memory; } /** Creates a valid, random id for a given object */ getId(value) { return nanoid() + "-" + (typeof value === "function" ? "f" : "o"); } registerRootObject(value) { const id = this.getId(value); this.rootReferences.set(id, value); return id; } registerTempObject(value) { const id = this.getId(value); this.temporaryReferences.set(id, value); return id; } clearTemporary() { this.temporaryReferences.clear(); } getObject(id) { return this.rootReferences.get(id) ?? this.temporaryReferences.get(id); } // A serializePostMessage isn't needed here, because all we're ever going to pass to the worker are ids serializeMemory(value, memory) { // Format: // [1 byte][n bytes ] // [type ][data ] memory.writeSize(8); // Anything that fits into 8 bytes is fine // Simple primitives. Guaranteed to fit into the shared memory. if (value === undefined) { memory.memory[0] = SERIALIZATION.UNDEFINED; memory.unlockSize(); } else if (value === null) { memory.memory[0] = SERIALIZATION.NULL; memory.unlockSize(); } else if (value === false) { memory.memory[0] = SERIALIZATION.FALSE; memory.unlockSize(); } else if (value === true) { memory.memory[0] = SERIALIZATION.TRUE; memory.unlockSize(); } else if (typeof value === "number") { memory.memory[0] = SERIALIZATION.NUMBER; memory.memory.set(encodeFloat(value), 1); memory.unlockSize(); } else if (value instanceof Date) { memory.memory[0] = SERIALIZATION.DATE; const time = value.getTime(); memory.memory.set(encodeFloat(time), 1); memory.unlockSize(); } else if (typeof value === "symbol" && KNOWN_SYMBOLS.includes(value)) { memory.memory[0] = SERIALIZATION.KNOWN_SYMBOL; memory.memory[1] = KNOWN_SYMBOLS.indexOf(value); memory.unlockSize(); } // Variable length primitives. Not guaranteed to fit into the shared memory, but we know their size. else if (typeof value === "string") { memory.memory[0] = SERIALIZATION.STRING; // A string encoded in utf-8 uses at most 4 bytes per character if (value.length * 4 <= memory.memory.byteLength) { const data = textEncoder.encode(value); memory.memory.set(data, 1); memory.writeSize(data.byteLength); memory.unlockSize(); } else { // Longer strings need to be sent piece by piece const bytes = textEncoder.encode(value); const memorySize = memory.memory.byteLength; let offset = 0; let remainingBytes = bytes.byteLength; memory.memory.set(bytes.subarray(offset, memorySize - 1), 1); offset += memorySize - 1; remainingBytes -= memorySize - 1; this.writeMemoryContinuation = () => { if (remainingBytes > 0) { memory.memory.set(bytes.subarray(offset, memorySize), 0); offset += memorySize; remainingBytes -= memorySize; } else { this.writeMemoryContinuation = undefined; } memory.unlockSize(); }; memory.writeSize(bytes.byteLength); memory.unlockSize(); } } else if (typeof value === "bigint") { memory.memory[0] = SERIALIZATION.BIGINT; value.toString(); // TODO: Implement this (just like the text ^) console.warn("Bigint support is not implemented"); memory.unlockSize(); } // Object. Serialized as ID, guaranteed to fit into shared memory else { memory.memory[0] = SERIALIZATION.OBJECT; const id = this.registerTempObject(value); const data = textEncoder.encode(id); memory.memory.set(data, 1); memory.writeSize(data.byteLength); memory.unlockSize(); } } /** * Deserializes an object that was sent through postMessage */ deserializePostMessage(value) { if (typeof value === "object" && value !== null) { // Special cases if (value.id) return this.getObject(value.id); if (value.value) return value.value; if (value.symbol) return KNOWN_SYMBOLS[value.symbol]; } // It's a primitive return value; } handleProxyMessage(message, memory) { if (message.type === "proxy_reflect") { try { if (message.method === "apply") { const method = Reflect[message.method]; const args = (message.args ?? []).map((v) => this.deserializePostMessage(v)); const result = method(this.getObject(message.target), this.getObject(message.thisArg), args); // Write result to shared memory this.serializeMemory(result, memory); } else { const method = Reflect[message.method]; const args = (message.args ?? []).map((v) => this.deserializePostMessage(v)); const result = method(this.getObject(message.target), ...args); // Write result to shared memory this.serializeMemory(result, memory); } } catch (e) { console.error(message); throw e; } } else if (message.type === "proxy_shared_memory") { // Write remaining data to shared memory if (this.writeMemoryContinuation === undefined) { console.warn("No more data to write to shared memory"); } else { this.writeMemoryContinuation(); } } else if (message.type === "proxy_print_object") { console.log("Object with id", message.target, "is", this.getObject(message.target)); } else if (message.type === "proxy_promise") { const promiseObject = this.getObject(message.target); if (message.method === "then") { promiseObject[message.method]((value) => { const result = { value: value }; this.serializeMemory(result, memory); }, (err) => { const result = { error: err }; this.serializeMemory(result, memory); }); } else { console.error("Unknown proxy promise method", message); } } else { console.warn("Unknown proxy message", message); } } } const ObjectId = Symbol.for("id"); async function mainThreadPyodide(opts, drawCanvas) { const pyodideWorkerOptions = opts.options; pyodideWorkerOptions.globalThisId = ""; pyodideWorkerOptions.drawCanvasId = ""; pyodideWorkerOptions.isMainThread = true; const fakeKernel = { proxy: undefined, postMessage(message) { }, syncFs: undefined, input: () => { return prompt() || ""; }, kernels: new Map(), log(kernel, ...args) { console.log(...args); }, logWarning(kernel, ...args) { console.warn(...args); }, logError(kernel, ...args) { console.error(...args); }, [ObjectId]: "", }; globalThis.manager = fakeKernel; const kernel = await new Promise((resolve, reject) => { try { const script = document.createElement("script"); const onLoad = () => { const KernelClass = globalThis[opts.className]; if (!opts.options.id) { opts.options.id = opts.kernelId; } const kernel = new KernelClass(pyodideWorkerOptions); kernel.init().then(() => { resolve(kernel); }); }; if (opts.source.type === "url") { script.addEventListener("load", onLoad); script.src = opts.source.url; document.head.appendChild(script); } else { script.text = opts.source.code; document.head.appendChild(script); onLoad(); } } catch (e) { reject(e); } }); // Not quite as elegant as it could be, but whatevs kernel.proxiedDrawCanvas = drawCanvas; return kernel; } var kernelWorkerScriptSource = "class AsyncMemory{constructor(sharedLock,sharedMemory){this.sharedLock=sharedLock??new SharedArrayBuffer(8*Int32Array.BYTES_PER_ELEMENT);this.lockAndSize=new Int32Array(this.sharedLock);if(this.lockAndSize.length<8)throw new Error(\"Expected an sharedLock with at least 8x32 bytes\");this.sharedMemory=sharedMemory??new SharedArrayBuffer(1024);this.memory=new Uint8Array(this.sharedMemory);if(this.sharedMemory.byteLength<1024)throw new Error(\"Expected an sharedMemory with at least 1024 bytes\")}lockWorker(){const oldValue=Atomics.compareExchange(this.lockAndSize,AsyncMemory.LOCK_WORKER_INDEX,AsyncMemory.UNLOCKED,AsyncMemory.LOCKED);if(oldValue!==AsyncMemory.UNLOCKED)throw new Error(`Cannot lock worker, the worker has to be unlocked ${AsyncMemory.UNLOCKED} !== ${oldValue}`)}lockSize(){const oldValue=Atomics.compareExchange(this.lockAndSize,AsyncMemory.LOCK_SIZE_INDEX,AsyncMemory.UNLOCKED,AsyncMemory.LOCKED);if(oldValue!==AsyncMemory.UNLOCKED)throw new Error(`Cannot set size flag, the size has to be unlocked ${AsyncMemory.UNLOCKED} !== ${oldValue}`)}waitForSize(){Atomics.wait(this.lockAndSize,AsyncMemory.LOCK_SIZE_INDEX,AsyncMemory.LOCKED)}writeSize(value){return Atomics.store(this.lockAndSize,AsyncMemory.SIZE_INDEX,value)}readSize(){return Atomics.load(this.lockAndSize,AsyncMemory.SIZE_INDEX)}unlockSize(){const oldValue=Atomics.compareExchange(this.lockAndSize,AsyncMemory.LOCK_SIZE_INDEX,AsyncMemory.LOCKED,AsyncMemory.UNLOCKED);if(oldValue!=AsyncMemory.LOCKED)throw new Error(\"Tried to unlock, but was already unlocked\");Atomics.notify(this.lockAndSize,AsyncMemory.LOCK_SIZE_INDEX)}forceUnlockSize(){const oldValue=Atomics.compareExchange(this.lockAndSize,AsyncMemory.LOCK_SIZE_INDEX,AsyncMemory.LOCKED,AsyncMemory.UNLOCKED);if(oldValue!=AsyncMemory.LOCKED)Atomics.store(this.lockAndSize,AsyncMemory.LOCK_SIZE_INDEX,AsyncMemory.UNLOCKED);Atomics.notify(this.lockAndSize,AsyncMemory.LOCK_SIZE_INDEX)}unlockWorker(){const oldValue=Atomics.compareExchange(this.lockAndSize,AsyncMemory.LOCK_WORKER_INDEX,AsyncMemory.LOCKED,AsyncMemory.UNLOCKED);if(oldValue!=AsyncMemory.LOCKED)throw new Error(\"Tried to unlock, but was already unlocked\");Atomics.notify(this.lockAndSize,AsyncMemory.LOCK_WORKER_INDEX)}}AsyncMemory.LOCK_WORKER_INDEX=0;AsyncMemory.LOCK_SIZE_INDEX=2;AsyncMemory.SIZE_INDEX=4;AsyncMemory.UNLOCKED=0;AsyncMemory.LOCKED=1;const SERIALIZATION={UNDEFINED:0,NULL:1,FALSE:2,TRUE:3,NUMBER:4,DATE:5,KNOWN_SYMBOL:6,STRING:10,BIGINT:11,OBJECT:255};const KNOWN_SYMBOLS=[Symbol.asyncIterator,Symbol.hasInstance,Symbol.isConcatSpreadable,Symbol.iterator,Symbol.match,Symbol.matchAll,Symbol.replace,Symbol.search,Symbol.species,Symbol.split,Symbol.toPrimitive,Symbol.toStringTag,Symbol.unscopables];new TextEncoder;const textDecoder=new TextDecoder(\"utf-8\");const decodeFloat=useFloatDecoder();function useFloatDecoder(){const temp=new ArrayBuffer(8);const tempFloat64=new Float64Array(temp);const tempUint8=new Uint8Array(temp);return function(value){tempUint8.set(value);return tempFloat64[0]}}const ObjectId=Symbol.for(\"id\");class ObjectProxyClient{constructor(memory,postMessage){this.memory=memory;this.postMessage=postMessage}serializePostMessage(value){if(isSimplePrimitive(value))return value;else if(isSymbolPrimitive(value))return{symbol:KNOWN_SYMBOLS.indexOf(value)};else if(isVariableLengthPrimitive(value))return value;else if(void 0!==value[ObjectId])return{id:value[ObjectId]};else return{value}}deserializeMemory(memory){const numberOfBytes=memory.readSize();let resultBytes;if(numberOfBytes<=memory.sharedMemory.byteLength)resultBytes=memory.memory;else{const memorySize=memory.sharedMemory.byteLength;let offset=0;let remainingBytes=numberOfBytes;resultBytes=new Uint8Array(numberOfBytes);while(remainingBytes>=memorySize){resultBytes.set(memory.memory,offset);offset+=memorySize;remainingBytes-=memorySize;memory.lockSize();this.postMessage({type:\"proxy_shared_memory\"});memory.waitForSize()}if(remainingBytes>0)resultBytes.set(memory.memory.subarray(0,remainingBytes),offset)}if(resultBytes[0]===SERIALIZATION.UNDEFINED)return;else if(resultBytes[0]===SERIALIZATION.NULL)return null;else if(resultBytes[0]===SERIALIZATION.FALSE)return!1;else if(resultBytes[0]===SERIALIZATION.TRUE)return!0;else if(resultBytes[0]===SERIALIZATION.NUMBER)return decodeFloat(resultBytes.subarray(1,9));else if(resultBytes[0]===SERIALIZATION.DATE){const date=new Date;date.setTime(decodeFloat(resultBytes.subarray(1,9)));return date}else if(resultBytes[0]===SERIALIZATION.KNOWN_SYMBOL){const symbol=KNOWN_SYMBOLS[resultBytes[1]];return symbol}else if(resultBytes[0]===SERIALIZATION.STRING)return textDecoder.decode(resultBytes.slice(1,numberOfBytes+1));else if(resultBytes[0]===SERIALIZATION.BIGINT)return BigInt(textDecoder.decode(resultBytes.slice(1,numberOfBytes+1)));else if(resultBytes[0]===SERIALIZATION.OBJECT){const id=textDecoder.decode(resultBytes.slice(1,numberOfBytes+1));return this.getObjectProxy(id)}else{console.warn(\"Unknown type\",resultBytes[0]);return null}}proxyReflect(method,targetId,args){let value;try{this.memory.lockWorker();this.memory.lockSize();this.memory.writeSize(0);if(\"apply\"===method)this.postMessage({type:\"proxy_reflect\",method,target:targetId,thisArg:args[0],args:args[1].map((v=>this.serializePostMessage(v)))});else this.postMessage({type:\"proxy_reflect\",method,target:targetId,args:args.map((v=>this.serializePostMessage(v)))});this.memory.waitForSize();value=this.deserializeMemory(this.memory)}catch(e){console.error({method,targetId,args});console.error(e);this.postMessage({type:\"proxy_print_object\",target:targetId})}finally{this.memory.forceUnlockSize();this.memory.unlockWorker()}return value}proxyPromise(method,targetId){let value;try{this.memory.lockWorker();this.memory.lockSize();this.memory.writeSize(0);this.postMessage({type:\"proxy_promise\",method,target:targetId});this.memory.waitForSize();value=this.deserializeMemory(this.memory)}catch(e){console.error({method,targetId});console.error(e);this.postMessage({type:\"proxy_print_object\",target:targetId})}finally{this.memory.forceUnlockSize();this.memory.unlockWorker()}return value}isFunction(id){return id.endsWith(\"-f\")}getObjectProxy(id){const client=this;return new Proxy(this.isFunction(id)?function(){}:{},{get(target,prop,receiver){if(prop===ObjectId)return id;const value=client.proxyReflect(\"get\",id,[prop,receiver]);if(\"function\"!==typeof value)return value;return new Proxy(value,{apply(_,thisArg,argumentsList){const calledWithProxy=thisArg===receiver;const functionReturnValue=client.proxyReflect(\"apply\",value[ObjectId],[calledWithProxy?id:thisArg[ObjectId],argumentsList]);return functionReturnValue}})},set(target,prop,value,receiver){return client.proxyReflect(\"set\",id,[prop,value,receiver])},ownKeys(target){return client.proxyReflect(\"ownKeys\",id,[])},has(target,prop){return client.proxyReflect(\"has\",id,[prop])},defineProperty(target,prop,attributes){return client.proxyReflect(\"defineProperty\",id,[prop,attributes])},deleteProperty(target,prop){return client.proxyReflect(\"deleteProperty\",id,[prop])},apply(target,thisArg,argumentsList){return client.proxyReflect(\"apply\",id,[thisArg[ObjectId],argumentsList])},construct(target,argumentsList,newTarget){return client.proxyReflect(\"construct\",id,[argumentsList,newTarget])}})}wrapExcluderProxy(obj,underlyingObject,exclude){return new Proxy(obj,{get(target,prop,receiver){if(exclude.has(prop))target=underlyingObject;const value=Reflect.get(target,prop,receiver);if(\"function\"!==typeof value)return value;return new Proxy(value,{apply(_,thisArg,args){const calledWithProxy=thisArg===receiver;return Reflect.apply(value,calledWithProxy?target:thisArg,args)}})},has(target,prop){if(exclude.has(prop))target=underlyingObject;return Reflect.has(target,prop)}})}thenSync(obj){const objectId=obj[ObjectId];if(!objectId)throw new Error(\"Not a proxy object\");const result=this.proxyPromise(\"then\",objectId);if(result.error)throw result.error;return result.value}}function isSimplePrimitive(value){if(void 0===value)return!0;else if(null===value)return!0;else if(!1===value)return!0;else if(!0===value)return!0;else if(\"number\"===typeof value)return!0;else if(value instanceof Date)return!0;else return!1}function isSymbolPrimitive(value){if(\"symbol\"===typeof value&&KNOWN_SYMBOLS.includes(value))return!0;return!1}function isVariableLengthPrimitive(value){if(\"string\"===typeof value)return!0;else if(\"bigint\"===typeof value)return!0}var _a;function assertUnreachable(_x){throw new Error(\"This case should have never been reached\")}class KernelManager{constructor(){this.kernels=new Map;this.input=()=>\"\\n\";this[_a]=\"\";self.addEventListener(\"message\",(async e=>{if(!e.data){console.warn(\"Kernel worker received unexpected message:\",e);return}const data=e.data;switch(data.type){case\"initialize\":if(data.asyncMemory){const asyncMemory=new AsyncMemory(data.asyncMemory.lockBuffer,data.asyncMemory.dataBuffer);this.proxy=new ObjectProxyClient(asyncMemory,(message=>{this.postMessage(message)}));if(data.getInputId)this.input=this.proxy.getObjectProxy(data.getInputId);if(data.filesystemId){const proxy=this.proxy;const asyncFs=this.proxy.getObjectProxy(data.filesystemId);this.syncFs={get(opts){return proxy.thenSync(asyncFs.get(opts))},put(opts){return proxy.thenSync(asyncFs.put(opts))},delete(opts){return proxy.thenSync(asyncFs.delete(opts))},move(opts){return proxy.thenSync(asyncFs.move(opts))},listDirectory(opts){return proxy.thenSync(asyncFs.listDirectory(opts))}}}}else console.warn(\"Missing async memory, accessing objects from the main thread will not work. Please make sure that COOP/COEP is enabled.\");break;case\"import_kernel\":try{if(\"url\"===data.source.type)importScripts(data.source.url);else{const blob=new Blob([data.source.code],{type:\"text/javascript\"});importScripts(URL.createObjectURL(blob))}const KernelClass=globalThis[data.className];if(!data.options.id)data.options.id=data.kernelId;const kernel=new KernelClass(data.options);this.kernels.set(kernel.kernelId,kernel);kernel.init().then((()=>{this.postMessage({type:\"kernel_initialized\",kernelId:kernel.kernelId})}))}catch(e){this.postMessage({type:\"error\",kernelId:data.kernelId,id:\"\",error:e+\"\"})}break;case\"run\":try{const kernel=this.kernels.get(data.kernelId);if(!kernel)throw new Error(\"Failed to find kernel with id \"+data.kernelId);const result=await kernel.runCode(data.code);this.postMessage({type:\"result\",kernelId:kernel.kernelId,id:data.id,value:result})}catch(e){this.postMessage({type:\"error\",kernelId:data.kernelId,id:data.id,error:e+\"\"})}break;case\"custom\":{const kernel=this.kernels.get(data.kernelId);if(kernel)kernel.customMessage(data.message);else console.warn(\"Custom message was sent to an nonexistent kernel\",data);break}default:assertUnreachable();break}}))}postMessage(message){self.postMessage(message)}log(kernel,...args){this.postMessage({kernelId:kernel.kernelId,type:\"console\",method:\"log\",data:args})}logWarning(kernel,...args){this.postMessage({kernelId:kernel.kernelId,type:\"console\",method:\"warn\",data:args})}logError(kernel,...args){this.postMessage({kernelId:kernel.kernelId,type:\"console\",method:\"error\",data:args})}}_a=ObjectId;globalThis.manager=new KernelManager;\n"; var pyodideWorkerScriptSource = "var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __commonJS=(cb,mod)=>function __require(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __copyProps=(to,from,except,desc)=>{if(from&&\"object\"===typeof from||\"function\"===typeof from)for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toESM=(mod,isNodeMode,target)=>(target=null!=mod?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,\"default\",{value:mod,enumerable:!0}):target,mod));var require_stackframe=__commonJS({\"node_modules/stackframe/stackframe.js\"(exports,module){(function(root,factory){if(\"function\"===typeof define&&define.amd)define(\"stackframe\",[],factory);else if(\"object\"===typeof exports)module.exports=factory();else root.StackFrame=factory()})(exports,(function(){function _isNumber(n){return!isNaN(parseFloat(n))&&isFinite(n)}function _capitalize(str){return str.charAt(0).toUpperCase()+str.substring(1)}function _getter(p){return function(){return this[p]}}var booleanProps=[\"isConstructor\",\"isEval\",\"isNative\",\"isToplevel\"];var numericProps=[\"columnNumber\",\"lineNumber\"];var stringProps=[\"fileName\",\"functionName\",\"source\"];var arrayProps=[\"args\"];var objectProps=[\"evalOrigin\"];var props=booleanProps.concat(numericProps,stringProps,arrayProps,objectProps);function StackFrame(obj){if(!obj)return;for(var i2=0;i2<props.length;i2++)if(void 0!==obj[props[i2]])this[\"set\"+_capitalize(props[i2])](obj[props[i2]])}StackFrame.prototype={getArgs:function(){return this.args},setArgs:function(v){if(\"[object Array]\"!==Object.prototype.toString.call(v))throw new TypeError(\"Args must be an Array\");this.args=v},getEvalOrigin:function(){return this.evalOrigin},setEvalOrigin:function(v){if(v instanceof StackFrame)this.evalOrigin=v;else if(v instanceof Object)this.evalOrigin=new StackFrame(v);else throw new TypeError(\"Eval Origin must be an Object or StackFrame\")},toString:function(){var fileName=this.getFileName()||\"\";var lineNumber=this.getLineNumber()||\"\";var columnNumber=this.getColumnNumber()||\"\";var functionName=this.getFunctionName()||\"\";if(this.getIsEval()){if(fileName)return\"[eval] (\"+fileName+\":\"+lineNumber+\":\"+columnNumber+\")\";return\"[eval]:\"+lineNumber+\":\"+columnNumber}if(functionName)return functionName+\" (\"+fileName+\":\"+lineNumber+\":\"+columnNumber+\")\";return fileName+\":\"+lineNumber+\":\"+columnNumber}};StackFrame.fromString=function StackFrame$$fromString(str){var argsStartIndex=str.indexOf(\"(\");var argsEndIndex=str.lastIndexOf(\")\");var functionName=str.substring(0,argsStartIndex);var args=str.substring(argsStartIndex+1,argsEndIndex).split(\",\");var locationString=str.substring(argsEndIndex+1);if(0===locationString.indexOf(\"@\")){var parts=/@(.+?)(?::(\\d+))?(?::(\\d+))?$/.exec(locationString,\"\");var fileName=parts[1];var lineNumber=parts[2];var columnNumber=parts[3]}return new StackFrame({functionName,args:args||void 0,fileName,lineNumber:lineNumber||void 0,columnNumber:columnNumber||void 0})};for(var i=0;i<booleanProps.length;i++){StackFrame.prototype[\"get\"+_capitalize(booleanProps[i])]=_getter(booleanProps[i]);StackFrame.prototype[\"set\"+_capitalize(booleanProps[i])]=function(p){return function(v){this[p]=Boolean(v)}}(booleanProps[i])}for(var j=0;j<numericProps.length;j++){StackFrame.prototype[\"get\"+_capitalize(numericProps[j])]=_getter(numericProps[j]);StackFrame.prototype[\"set\"+_capitalize(numericProps[j])]=function(p){return function(v){if(!_isNumber(v))throw new TypeError(p+\" must be a Number\");this[p]=Number(v)}}(numericProps[j])}for(var k=0;k<stringProps.length;k++){StackFrame.prototype[\"get\"+_capitalize(stringProps[k])]=_getter(stringProps[k]);StackFrame.prototype[\"set\"+_capitalize(stringProps[k])]=function(p){return function(v){this[p]=String(v)}}(stringProps[k])}return StackFrame}))}});var require_error_stack_parser=__commonJS({\"node_modules/error-stack-parser/error-stack-parser.js\"(exports,module){(function(root,factory){if(\"function\"===typeof define&&define.amd)define(\"error-stack-parser\",[\"stackframe\"],factory);else if(\"object\"===typeof exports)module.exports=factory(require_stackframe());else root.ErrorStackParser=factory(root.StackFrame)})(exports,(function ErrorStackParser3(StackFrame){var FIREFOX_SAFARI_STACK_REGEXP=/(^|@)\\S+:\\d+/;var CHROME_IE_STACK_REGEXP=/^\\s*at .*(\\S+:\\d+|\\(native\\))/m;var SAFARI_NATIVE_CODE_REGEXP=/^(eval@)?(\\[native code])?$/;return{parse:function ErrorStackParser$$parse(error){if(\"undefined\"!==typeof error.stacktrace||\"undefined\"!==typeof error[\"opera#sourceloc\"])return this.parseOpera(error);else if(error.stack&&error.stack.match(CHROME_IE_STACK_REGEXP))return this.parseV8OrIE(error);else if(error.stack)return this.parseFFOrSafari(error);else throw new Error(\"Cannot parse given Error object\")},extractLocation:function ErrorStackParser$$extractLocation(urlLike){if(-1===urlLike.indexOf(\":\"))return[urlLike];var regExp=/(.+?)(?::(\\d+))?(?::(\\d+))?$/;var parts=regExp.exec(urlLike.replace(/[()]/g,\"\"));return[parts[1],parts[2]||void 0,parts[3]||void 0]},parseV8OrIE:function ErrorStackParser$$parseV8OrIE(error){var filtered=error.stack.split(\"\\n\").filter((function(line){return!!line.match(CHROME_IE_STACK_REGEXP)}),this);return filtered.map((function(line){if(line.indexOf(\"(eval \")>-1)line=line.replace(/eval code/g,\"eval\").replace(/(\\(eval at [^()]*)|(,.*$)/g,\"\");var sanitizedLine=line.replace(/^\\s+/,\"\").replace(/\\(eval code/g,\"(\").replace(/^.*?\\s+/,\"\");var location2=sanitizedLine.match(/ (\\(.+\\)$)/);sanitizedLine=location2?sanitizedLine.replace(location2[0],\"\"):sanitizedLine;var locationParts=this.extractLocation(location2?location2[1]:sanitizedLine);var functionName=location2&&sanitizedLine||void 0;var fileName=[\"eval\",\"<anonymous>\"].indexOf(locationParts[0])>-1?void 0:locationParts[0];return new StackFrame({functionName,fileName,lineNumber:locationParts[1],columnNumber:locationParts[2],source:line})}),this)},parseFFOrSafari:function ErrorStackParser$$parseFFOrSafari(error){var filtered=error.stack.split(\"\\n\").filter((function(line){return!line.match(SAFARI_NATIVE_CODE_REGEXP)}),this);return filtered.map((function(line){if(line.indexOf(\" > eval\")>-1)line=line.replace(/ line (\\d+)(?: > eval line \\d+)* > eval:\\d+:\\d+/g,\":$1\");if(-1===line.indexOf(\"@\")&&-1===line.indexOf(\":\"))return new StackFrame({functionName:line});else{var functionNameRegex=/((.*\".+\"[^@]*)?[^@]*)(?:@)/;var matches=line.match(functionNameRegex);var functionName=matches&&matches[1]?matches[1]:void 0;var locationParts=this.extractLocation(line.replace(functionNameRegex,\"\"));return new StackFrame({functionName,fileName:locationParts[0],lineNumber:locationParts[1],columnNumber:locationParts[2],source:line})}}),this)},parseOpera:function ErrorStackParser$$parseOpera(e){if(!e.stacktrace||e.message.indexOf(\"\\n\")>-1&&e.message.split(\"\\n\").length>e.stacktrace.split(\"\\n\").length)return this.parseOpera9(e);else if(!e.stack)return this.parseOpera10(e);else return this.parseOpera11(e)},parseOpera9:function ErrorStackParser$$parseOpera9(e){var lineRE=/Line (\\d+).*script (?:in )?(\\S+)/i;var lines=e.message.split(\"\\n\");var result=[];for(var i=2,len=lines.length;i<len;i+=2){var match=lineRE.exec(lines[i]);if(match)result.push(new StackFrame({fileName:match[2],lineNumber:match[1],source:lines[i]}))}return result},parseOpera10:function ErrorStackParser$$parseOpera10(e){var lineRE=/Line (\\d+).*script (?:in )?(\\S+)(?:: In function (\\S+))?$/i;var lines=e.stacktrace.split(\"\\n\");var result=[];for(var i=0,len=lines.length;i<len;i+=2){var match=lineRE.exec(lines[i]);if(match)result.push(new StackFrame({functionName:match[3]||void 0,fileName:match[2],lineNumber:match[1],source:lines[i]}))}return result},parseOpera11:function ErrorStackParser$$parseOpera11(error){var filtered=error.stack.split(\"\\n\").filter((function(line){return!!line.match(FIREFOX_SAFARI_STACK_REGEXP)&&!line.match(/^Error created at/)}),this);return filtered.map((function(line){var tokens=line.split(\"@\");var locationParts=this.extractLocation(tokens.pop());var functionCall=tokens.shift()||\"\";var functionName=functionCall.replace(/<anonymous function(: (\\w+))?>/,\"$2\").replace(/\\([^)]*\\)/g,\"\")||void 0;var argsRaw;if(functionCall.match(/\\(([^)]*)\\)/))argsRaw=functionCall.replace(/^[^(]+\\(([^)]*)\\)$/,\"$1\");var args=void 0===argsRaw||\"[arguments not available]\"===argsRaw?void 0:argsRaw.split(\",\");return new StackFrame({functionName,args,fileName:locationParts[0],lineNumber:locationParts[1],columnNumber:locationParts[2],source:line})}),this)}}}))}});var require_browser=__commonJS({\"node_modules/node-fetch/browser.js\"(exports,module){var getGlobal=function(){if(\"undefined\"!==typeof self)return self;if(\"undefined\"!==typeof window)return window;if(\"undefined\"!==typeof global)return global;throw new Error(\"unable to locate global object\")};var global=getGlobal();module.exports=exports=global.fetch;if(global.fetch)exports.default=global.fetch.bind(global);exports.Headers=global.Headers;exports.Request=global.Request;exports.Response=global.Response}});var import_error_stack_parser2=__toESM(require_error_stack_parser(),1);var Module={};Module.noImageDecoding=!0;Module.noAudioDecoding=!0;Module.noWasmDecoding=!1;Module.preloadedWasm={};Module.preRun=[];var API={};Module.API=API;var Hiwire={};Module.hiwire=Hiwire;var Tests={};API.tests=Tests;function setStandardStreams(stdin,stdout,stderr){if(stdout)Module.print=stdout;if(stderr)Module.printErr=stderr;if(stdin)Module.preRun.push((function(){Module.FS.init(createStdinWrapper(stdin),null,null)}))}function createStdinWrapper(stdin){const encoder=new TextEncoder;let input=new Uint8Array(0);let inputIndex=-1;function stdinWrapper(){try{if(-1===inputIndex){let text=stdin();if(void 0===text||null===text)return null;if(\"string\"!==typeof text)throw new TypeError(`Expected stdin to return string, null, or undefined, got type ${typeof text}.`);if(!text.endsWith(\"\\n\"))text+=\"\\n\";input=encoder.encode(text);inputIndex=0}if(inputIndex<input.length){let character=input[inputIndex];inputIndex++;return character}else{inputIndex=-1;return null}}catch(e){console.error(\"Error thrown in stdin:\");console.error(e);throw e}}return stdinWrapper}function setHomeDirectory(path){Module.preRun.push((function(){const fallbackPath=\"/\";try{Module.FS.mkdirTree(path)}catch(e){console.error(`Error occurred while making a home directory '${path}':`);console.error(e);console.error(`Using '${fallbackPath}' for a home directory instead`);path=fallbackPath}Module.ENV.HOME=path;Module.FS.chdir(path)}))}var IN_NODE=\"undefined\"!==typeof process&&process.release&&\"node\"===process.release.name&&\"undefined\"===typeof process.browser;var nodePathMod;var nodeFetch;var nodeVmMod;var nodeFsPromisesMod;async function initNodeModules(){if(!IN_NODE)return;nodePathMod=(await import(\"path\")).default;nodeFsPromisesMod=await import(\"fs/promises\");nodeFetch=(await Promise.resolve().then((()=>__toESM(require_browser(),1)))).default;nodeVmMod=(await import(\"vm\")).default}async function node_loadBinaryFile(indexURL,path){if(path.includes(\"://\")){let response=await nodeFetch(path);if(!response.ok)throw new Error(`Failed to load '${path}': request failed.`);return await response.arrayBuffer()}else{const data=await nodeFsPromisesMod.readFile(`${indexURL}${path}`);return new Uint8Array(data.buffer,data.byteOffset,data.byteLength)}}async function browser_loadBinaryFile(indexURL,path){const base=new URL(indexURL,location);const url=new URL(path,base);let response=await fetch(url);if(!response.ok)throw new Error(`Failed to load '${url}': request failed.`);return new Uint8Array(await response.arrayBuffer())}var _loadBinaryFile;if(IN_NODE)_loadBinaryFile=node_loadBinaryFile;else _loadBinaryFile=browser_loadBinaryFile;var loadScript;if(globalThis.document)loadScript=async url=>await import(url);else if(globalThis.importScripts)loadScript=async url=>{try{globalThis.importScripts(url)}catch(e){if(e instanceof TypeError)await import(url);else throw e}};else if(IN_NODE)loadScript=nodeLoadScript;else throw new Error(\"Cannot determine runtime environment\");async function nodeLoadScript(url){if(url.includes(\"://\"))nodeVmMod.runInThisContext(await(await nodeFetch(url)).text());else await import(nodePathMod.resolve(url))}function isPyProxy(jsobj){return!!jsobj&&void 0!==jsobj.$$&&\"PyProxy\"===jsobj.$$.type}API.isPyProxy=isPyProxy;if(globalThis.FinalizationRegistry)Module.finalizationRegistry=new FinalizationRegistry((([ptr,cache])=>{cache.leaked=!0;pyproxy_decref_cache(cache);try{Module._Py_DecRef(ptr)}catch(e){API.fatal_error(e)}}));else Module.finalizationRegistry={register(){},unregister(){}};var pyproxy_alloc_map=new Map;Module.pyproxy_alloc_map=pyproxy_alloc_map;var trace_pyproxy_alloc;var trace_pyproxy_dealloc;Module.enable_pyproxy_allocation_tracing=function(){trace_pyproxy_alloc=function(proxy){pyproxy_alloc_map.set(proxy,Error().stack)};trace_pyproxy_dealloc=function(proxy){pyproxy_alloc_map.delete(proxy)}};Module.disable_pyproxy_allocation_tracing=function(){trace_pyproxy_alloc=function(proxy){};trace_pyproxy_dealloc=function(proxy){}};Module.disable_pyproxy_allocation_tracing();Module.pyproxy_new=function(ptrobj,cache){let flags=Module._pyproxy_getflags(ptrobj);let cls=Module.getPyProxyClass(flags);let target;if(flags&1<<8){target=Reflect.construct(Function,[],cls);delete target.length;delete target.name;target.prototype=void 0}else target=Object.create(cls.prototype);if(!cache){let cacheId=Hiwire.new_value(new Map);cache={cacheId,refcnt:0}}cache.refcnt++;Object.defineProperty(target,\"$$\",{value:{ptr:ptrobj,type:\"PyProxy\",cache}});Module._Py_IncRef(ptrobj);let proxy=new Proxy(target,PyProxyHandlers);trace_pyproxy_alloc(proxy);Module.finalizationRegistry.register(proxy,[ptrobj,cache],proxy);return proxy};function _getPtr(jsobj){let ptr=jsobj.$$.ptr;if(0===ptr)throw new Error(jsobj.$$.destroyed_msg);return ptr}var pyproxyClassMap=new Map;Module.getPyProxyClass=function(flags){const FLAG_TYPE_PAIRS=[[1<<0,PyProxyLengthMethods],[1<<1,PyProxyGetItemMethods],[1<<2,PyProxySetItemMethods],[1<<3,PyProxyContainsMethods],[1<<4,PyProxyIterableMethods],[1<<5,PyProxyIteratorMethods],[1<<6,PyProxyAwaitableMethods],[1<<7,PyProxyBufferMethods],[1<<8,PyProxyCallableMethods]];let result=pyproxyClassMap.get(flags);if(result)return result;let descriptors={};for(let[feature_flag,methods]of FLAG_TYPE_PAIRS)if(flags&feature_flag)Object.assign(descriptors,Object.getOwnPropertyDescriptors(methods.prototype));descriptors.constructor=Object.getOwnPropertyDescriptor(PyProxyClass.prototype,\"constructor\");Object.assign(descriptors,Object.getOwnPropertyDescriptors({$$flags:flags}));let new_proto=Object.create(PyProxyClass.prototype,descriptors);function NewPyProxyClass(){}NewPyProxyClass.prototype=new_proto;pyproxyClassMap.set(flags,NewPyProxyClass);return NewPyProxyClass};Module.PyProxy_getPtr=_getPtr;var pyproxy_cache_destroyed_msg=\"This borrowed attribute proxy was automatically destroyed in the process of destroying the