Notebook
+ +-
+
- + + +
- + + +
코드 입력
+World
+-
+
- + + +
- + + + +
위니브월드 맵
+ +Terminal
+-
+
+
- + + +
- + + +
+<py-config> +[splashscreen] +autoclose = false +</py-config> +`; + var SplashscreenPlugin = class extends Plugin { + configure(config2) { + this.autoclose = true; + this.enabled = true; + if ("autoclose_loader" in config2) { + this.autoclose = config2.autoclose_loader; + showWarning(AUTOCLOSE_LOADER_DEPRECATED, "html"); + } + if (config2.splashscreen) { + this.autoclose = config2.splashscreen.autoclose ?? true; + this.enabled = config2.splashscreen.enabled ?? true; + } + } + beforeLaunch(_config) { + if (!this.enabled) { + return; + } + logger8.info("add py-splashscreen"); + customElements.define("py-splashscreen", PySplashscreen); + this.elem = document.createElement("py-splashscreen"); + document.body.append(this.elem); + document.addEventListener("py-status-message", (e) => { + const msg = e.detail; + this.elem.log(msg); + }); + } + afterStartup(_interpreter) { + if (this.autoclose && this.enabled) { + this.elem.close(); + } + } + onUserError(_error) { + if (this.elem !== void 0 && this.enabled) { + this.elem.close(); + } + } + }; + var PySplashscreen = class extends HTMLElement { + constructor() { + super(); + } + connectedCallback() { + this.innerHTML = ` `; + this.mount_name = this.id.split("-").join("_"); + this.operation = $("#pyscript-operation", document); + this.details = $("#pyscript-operation-details", document); + } + log(msg) { + const newLog = document.createElement("p"); + newLog.innerText = msg; + this.details.appendChild(newLog); + } + close() { + logger8.info("Closing"); + this.remove(); + } + }; + + // src/plugins/importmap.ts + var logger9 = getLogger("plugins/importmap"); + var ImportmapPlugin = class extends Plugin { + async afterSetup(interpreter2) { + for (const node of $$("script[type='importmap']", document)) { + const importmap = (() => { + try { + return JSON.parse(node.textContent); + } catch (e) { + const error = e; + showWarning("Failed to parse import map: " + error.message); + } + })(); + if (importmap?.imports == null) + continue; + for (const [name2, url] of Object.entries(importmap.imports)) { + if (typeof name2 != "string" || typeof url != "string") + continue; + let exports; + try { + exports = { ...await import(url) }; + } catch { + logger9.warn(`failed to fetch '${url}' for '${name2}'`); + continue; + } + logger9.info("Registering JS module", name2); + await interpreter2._remote.registerJsModule(name2, exports); + } + } + } + }; + + // src/plugins/stdiodirector.ts + var StdioDirector = class extends Plugin { + constructor(stdio) { + super(); + this._stdioMultiplexer = stdio; + } + /** Prior to a
pyscript.js
is deprecated, please use import js
instead.",
+ "html",
+ )
+ return js
+ raise AttributeError(f"module 'pyscript' has no attribute '{attr}'")
+
+
+__all__ = [
+ "HTML",
+ "write",
+ "display",
+ "Element",
+ "add_classes",
+ "create",
+ "run_until_complete",
+ "loop",
+ "Plugin",
+ "__version__",
+ "version_info",
+ "showWarning",
+ "when",
+]
+`], ["pyscript/_plugin.py", 'from _pyscript_js import define_custom_element\nfrom js import console\nfrom pyodide.ffi import create_proxy\n\n\nclass Plugin:\n def __init__(self, name=None):\n if not name:\n name = self.__class__.__name__\n\n self.name = name\n self._custom_elements = []\n self.app = None\n\n def init(self, app):\n self.app = app\n\n def configure(self, config):\n pass\n\n def afterSetup(self, interpreter):\n pass\n\n def afterStartup(self, interpreter):\n pass\n\n def beforePyScriptExec(self, interpreter, src, pyScriptTag):\n pass\n\n def afterPyScriptExec(self, interpreter, src, pyScriptTag, result):\n pass\n\n def beforePyReplExec(self, interpreter, src, outEl, pyReplTag):\n pass\n\n def afterPyReplExec(self, interpreter, src, outEl, pyReplTag, result):\n pass\n\n def onUserError(self, error):\n pass\n\n def register_custom_element(self, tag):\n """\n Decorator to register a new custom element as part of a Plugin and associate\n tag to it. Internally, it delegates the registration to the PyScript internal\n [JS] plugin manager, who actually creates the JS custom element that can be\n attached to the page and instantiate an instance of the class passing the custom\n element to the plugin constructor.\n\n Exammple:\n >> plugin = Plugin("PyTutorial")\n >> @plugin.register_custom_element("py-tutor")\n >> class PyTutor:\n >> def __init__(self, element):\n >> self.element = element\n """\n # TODO: Ideally would be better to use the logger.\n console.info(f"Defining new custom element {tag}")\n\n def wrapper(class_):\n # TODO: this is very pyodide specific but will have to do\n # until we have JS interface that works across interpreters\n define_custom_element(tag, create_proxy(class_)) # noqa: F821\n\n self._custom_elements.append(tag)\n return create_proxy(wrapper)\n'], ["pyscript/_mime.py", `import base64
+import html
+import io
+import re
+
+from js import console
+
+MIME_METHODS = {
+ "__repr__": "text/plain",
+ "_repr_html_": "text/html",
+ "_repr_markdown_": "text/markdown",
+ "_repr_svg_": "image/svg+xml",
+ "_repr_png_": "image/png",
+ "_repr_pdf_": "application/pdf",
+ "_repr_jpeg_": "image/jpeg",
+ "_repr_latex": "text/latex",
+ "_repr_json_": "application/json",
+ "_repr_javascript_": "application/javascript",
+ "savefig": "image/png",
+}
+
+
+def render_image(mime, value, meta):
+ # If the image value is using bytes we should convert it to base64
+ # otherwise it will return raw bytes and the browser will not be able to
+ # render it.
+ if isinstance(value, bytes):
+ value = base64.b64encode(value).decode("utf-8")
+
+ # This is the pattern of base64 strings
+ base64_pattern = re.compile(
+ r"^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$"
+ )
+ # If value doesn't match the base64 pattern we should encode it to base64
+ if len(value) > 0 and not base64_pattern.match(value):
+ value = base64.b64encode(value.encode("utf-8")).decode("utf-8")
+
+ data = f"data:{mime};charset=utf-8;base64,{value}"
+ attrs = " ".join(['{k}="{v}"' for k, v in meta.items()])
+ return f'{name}
is deprecated. \" + instead\n ns[name] = DeprecatedGlobal(name, obj, message)\n\n # function/classes defined in pyscript.py ===> pyscript.XXX\n pyscript_names = [\n \"PyItemTemplate\",\n \"PyListTemplate\",\n \"PyWidgetTheme\",\n \"add_classes\",\n \"create\",\n \"loop\",\n ]\n for name in pyscript_names:\n deprecate(\n name, globals()[name], f\"Please use pyscript.{name}
instead.\"\n )\n\n # stdlib modules ===> import XXX\n stdlib_names = [\n \"asyncio\",\n \"base64\",\n \"io\",\n \"sys\",\n \"time\",\n \"datetime\",\n \"pyodide\",\n \"micropip\",\n ]\n for name in stdlib_names:\n obj = __import__(name)\n deprecate(name, obj, f\"Please use import {name}
instead.\")\n\n # special case\n deprecate(\n \"dedent\", dedent, \"Please use from textwrap import dedent
instead.\"\n )\n\n # these are names that used to leak in the globals but they are just\n # implementation details. People should not use them.\n private_names = [\n \"eval_formatter\",\n \"format_mime\",\n \"identity\",\n \"render_image\",\n \"MIME_RENDERERS\",\n \"MIME_METHODS\",\n ]\n for name in private_names:\n obj = globals()[name]\n message = (\n f\"{name}
is deprecated. \"\n \"This is a private implementation detail of pyscript. \"\n \"You should not use it.\"\n )\n ns[name] = DeprecatedGlobal(name, obj, message)\n\n # these names are available as js.XXX\n for name in [\"document\", \"console\"]:\n obj = getattr(js, name)\n deprecate(name, obj, f\"Please use js.{name}
instead.\")\n\n # PyScript is special, use a different message\n message = (\n \"The PyScript
object is deprecated. \"\n \"Please use pyscript
instead.\"\n )\n ns[\"PyScript\"] = DeprecatedGlobal(\"PyScript\", PyScript, message)\n";
+
+ const logger = getLogger('pyscript/main');
+ /* High-level overview of the lifecycle of a PyScript App:
+
+ 1. pyscript.js is loaded by the browser. PyScriptApp().main() is called
+
+ 2. loadConfig(): search for py-config and compute the config for the app
+
+ 3. (it used to be "show the splashscreen", but now it's a plugin)
+
+ 4. loadRuntime(): start downloading the actual runtime (e.g. pyodide.js)
+
+ --- wait until (4) has finished ---
+
+ 5. now the pyodide src is available. Initialize the engine
+
+ 6. setup the environment, install packages
+
+ 6.5: call the Plugin.afterSetup() hook
+
+ 7. connect the py-script web component. This causes the execution of all the
+ user scripts
+
+ 8. initialize the rest of web components such as py-button, py-repl, etc.
+
+ More concretely:
+
+ - Points 1-4 are implemented sequentially in PyScriptApp.main().
+
+ - PyScriptApp.loadRuntime adds a
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 캐릭터 정보
+