code-playpad 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -7
- package/dist/{element-CJuhuMOP.js → element-DtCQVStG.js} +39 -4
- package/dist/element.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{javascript-CLly2mXM.js → javascript-Cv8I8Gkw.js} +1 -1
- package/dist/{pyodide-IYKXKyDw.js → pyodide-B8qzHgzU.js} +1 -1
- package/dist/react.js +1 -1
- package/dist/standalone.js +38 -3
- package/dist/{worker-runtime-BZHszOA3.js → worker-runtime-HpUlPmaH.js} +1 -1
- package/package.json +3 -4
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ No backend, no iframe, no sign-up.
|
|
|
9
9
|
**[Live demo →](https://code-playpad.swengr.com)**
|
|
10
10
|
|
|
11
11
|
```html
|
|
12
|
-
<script type="module" src="https://cdn.jsdelivr.net/npm/code-playpad@0.
|
|
12
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/code-playpad@0.2.0"></script>
|
|
13
13
|
|
|
14
14
|
<code-playpad height="180">
|
|
15
15
|
print("hello from a static page")
|
|
@@ -45,12 +45,16 @@ CodeMirror is a peer dependency so you never end up with two copies of
|
|
|
45
45
|
`lang-javascript`, `lang-json`) are **optional** — install only the ones you
|
|
46
46
|
use; a missing one degrades to plain text.
|
|
47
47
|
|
|
48
|
-
```
|
|
49
|
-
|
|
48
|
+
```js
|
|
49
|
+
import 'code-playpad/element'; // registers <code-playpad>
|
|
50
|
+
```
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
Importing for the side effect is enough. If your bundler is configured to drop
|
|
53
|
+
side-effect-only imports, register explicitly instead:
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
import { defineCodePlayPad } from 'code-playpad/element';
|
|
57
|
+
defineCodePlayPad();
|
|
54
58
|
```
|
|
55
59
|
|
|
56
60
|
From React:
|
|
@@ -73,7 +77,7 @@ so Next.js, Astro and SvelteKit need no dynamic import.
|
|
|
73
77
|
|
|
74
78
|
| | |
|
|
75
79
|
| --- | --- |
|
|
76
|
-
| **attributes** | `language`, `height`, `theme` (`light` \| `dark` \| `auto`), `readonly`, `autorun`, `stdin`, `persist`, `entry` |
|
|
80
|
+
| **attributes** | `language`, `height`, `min-height`, `max-height`, `theme` (`light` \| `dark` \| `auto`), `readonly`, `autorun`, `stdin`, `persist`, `entry` |
|
|
77
81
|
| **properties** | `code`, `files`, `entry`, `stdin`, `language` |
|
|
78
82
|
| **methods** | `run()`, `stop()`, `reset()`, `getCode()`, `getFiles()`, `openFile(name)`, `prewarm()` |
|
|
79
83
|
| **events** | `py-ready`, `py-run`, `py-output`, `py-error` |
|
|
@@ -91,6 +95,34 @@ document.addEventListener('py-output', (e) => {
|
|
|
91
95
|
Note `language`, not `lang` — `lang` is a standard HTML attribute for the
|
|
92
96
|
*human* language of an element's text.
|
|
93
97
|
|
|
98
|
+
## Sizing
|
|
99
|
+
|
|
100
|
+
`height` takes a number (pixels), any CSS length, or **`auto`** to fit the
|
|
101
|
+
snippet:
|
|
102
|
+
|
|
103
|
+
```html
|
|
104
|
+
<code-playpad height="auto">print("no dead space, no hidden lines")</code-playpad>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`auto` is usually what you want. A fixed height has to be guessed per snippet,
|
|
108
|
+
and no guess is right at every viewport width — lines wrap, so a 90-character
|
|
109
|
+
line is one row on a desktop and three on a phone.
|
|
110
|
+
|
|
111
|
+
Two bounds go with it:
|
|
112
|
+
|
|
113
|
+
```html
|
|
114
|
+
<!-- a long listing that should not push the page off screen -->
|
|
115
|
+
<code-playpad height="auto" max-height="400">…</code-playpad>
|
|
116
|
+
|
|
117
|
+
<!-- an answer box: one line of content, but room to type -->
|
|
118
|
+
<code-playpad height="auto" min-height="170"># Your code here</code-playpad>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`max-height` scrolls rather than clips. `min-height` grows the editor itself, so
|
|
122
|
+
the empty space below a short snippet is still part of the editor and clicking
|
|
123
|
+
it puts the cursor there. All three take a bare number as pixels, or any CSS
|
|
124
|
+
length (`40vh`, `30em`).
|
|
125
|
+
|
|
94
126
|
## Several files
|
|
95
127
|
|
|
96
128
|
A widget can hold a small project. Relative imports, packages, and data files
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
async function e(e){try{return await t(e)}catch(t){return console.warn(`[code-playpad] CodeMirror unavailable, using plain textarea:`,t),n(e)}}async function t(e){let[t,n,r,i,a,o]=await Promise.all([import(`@codemirror/view`),import(`@codemirror/state`),import(`@codemirror/commands`),import(`@codemirror/language`),import(`@codemirror/autocomplete`),import(`@codemirror/theme-one-dark`)]),{EditorView:s,keymap:c,lineNumbers:l,highlightActiveLine:u,highlightActiveLineGutter:d,highlightSpecialChars:f,drawSelection:p,rectangularSelection:m,crosshairCursor:h}=t,{EditorState:g,Compartment:_}=n,{defaultKeymap:v,history:y,historyKeymap:b,indentWithTab:x}=r,{syntaxHighlighting:S,defaultHighlightStyle:C,indentOnInput:w,bracketMatching:T,foldGutter:E,foldKeymap:D}=i,{autocompletion:O,closeBrackets:k,closeBracketsKeymap:A,completionKeymap:j}=a,M=new _,N=new _,P=new _,F=[s.theme({"&":{color:`#1f2328`,backgroundColor:`#ffffff`},".cm-gutters":{backgroundColor:`#f6f8fa`,color:`#8b949e`,border:`none`},".cm-activeLine":{backgroundColor:`#f6f8fa88`},".cm-activeLineGutter":{backgroundColor:`#eaeef2`},".cm-cursor":{borderLeftColor:`#1f2328`},"&.cm-focused .cm-selectionBackground, .cm-selectionBackground, ::selection":{backgroundColor:`#cfe3ff`}}),S(C,{fallback:!0})],I=e=>e?o.oneDark:F,L=c.of([{key:`Mod-Enter`,preventDefault:!0,run:()=>(e.onRun?.(),!0)},{key:`Shift-Enter`,preventDefault:!0,run:()=>(e.onRun?.(),!0)}]),R=e.dark,z=e.readOnly,B=e.language??[],V=t=>g.create({doc:t,extensions:[l(),d(),f(),y(),E(),p(),g.allowMultipleSelections.of(!0),w(),T(),k(),O(),m(),h(),u(),L,c.of([...A,...v,...b,...D,...j,x]),s.lineWrapping,P.of(B),M.of(I(R)),N.of(g.readOnly.of(z)),s.updateListener.of(t=>{t.docChanged&&e.onChange?.(t.state.doc.toString())})]}),H=new s({parent:e.parent,state:V(e.doc)}),U=new Map,W=e.name??``;return{fallback:!1,getCode:()=>H.state.doc.toString(),setCode(e){H.dispatch({changes:{from:0,to:H.state.doc.length,insert:e}})},openFile(e,t){if(e===W)return;U.set(W,H.state);let n=U.get(e);H.setState(n??V(t)),W=e,n&&H.dispatch({effects:[M.reconfigure(I(R)),N.reconfigure(g.readOnly.of(z)),P.reconfigure(B)]})},fileCode(e,t){if(e===W)return H.state.doc.toString();let n=U.get(e);return n?n.doc.toString():t},forgetFiles(e){for(let t of[...U.keys()])e.includes(t)||U.delete(t)},setTheme(e){R=e,H.dispatch({effects:M.reconfigure(I(R))})},setReadOnly(e){z=e,H.dispatch({effects:N.reconfigure(g.readOnly.of(z))})},setLanguage(e){B=e,H.dispatch({effects:P.reconfigure(B)})},focus:()=>H.focus(),destroy:()=>H.destroy()}}function n(e){let t=document.createElement(`textarea`);t.className=`cp-fallback-editor`,t.spellcheck=!1,t.value=e.doc,t.readOnly=e.readOnly,t.addEventListener(`input`,()=>e.onChange?.(t.value)),t.addEventListener(`keydown`,t=>{(t.metaKey||t.ctrlKey)&&t.key===`Enter`&&(t.preventDefault(),e.onRun?.())}),e.parent.appendChild(t);let n=new Map,r=e.name??``;return{fallback:!0,getCode:()=>t.value,setCode:e=>{t.value=e},openFile(e,i){e!==r&&(n.set(r,t.value),t.value=n.get(e)??i,r=e)},fileCode(e,i){return e===r?t.value:n.get(e)??i},forgetFiles(e){for(let t of[...n.keys()])e.includes(t)||n.delete(t)},setTheme:()=>{},setReadOnly:e=>{t.readOnly=e},setLanguage:()=>{},focus:()=>t.focus(),destroy:()=>t.remove()}}var r=new Map,i=new Map;function a(e,t){r.set(e,t)}function o(){return[...r.keys()]}function s(e){let t=i.get(e);if(t)return t;let n=r.get(e);if(!n)return Promise.reject(Error(`Unknown runtime "${e}". Registered: ${o().join(`, `)||`none`}`));let a=n().catch(t=>{throw i.delete(e),t});return i.set(e,a),a}a(`python`,()=>import(`./pyodide-
|
|
1
|
+
async function e(e){try{return await t(e)}catch(t){return console.warn(`[code-playpad] CodeMirror unavailable, using plain textarea:`,t),n(e)}}async function t(e){let[t,n,r,i,a,o]=await Promise.all([import(`@codemirror/view`),import(`@codemirror/state`),import(`@codemirror/commands`),import(`@codemirror/language`),import(`@codemirror/autocomplete`),import(`@codemirror/theme-one-dark`)]),{EditorView:s,keymap:c,lineNumbers:l,highlightActiveLine:u,highlightActiveLineGutter:d,highlightSpecialChars:f,drawSelection:p,rectangularSelection:m,crosshairCursor:h}=t,{EditorState:g,Compartment:_}=n,{defaultKeymap:v,history:y,historyKeymap:b,indentWithTab:x}=r,{syntaxHighlighting:S,defaultHighlightStyle:C,indentOnInput:w,bracketMatching:T,foldGutter:E,foldKeymap:D}=i,{autocompletion:O,closeBrackets:k,closeBracketsKeymap:A,completionKeymap:j}=a,M=new _,N=new _,P=new _,F=[s.theme({"&":{color:`#1f2328`,backgroundColor:`#ffffff`},".cm-gutters":{backgroundColor:`#f6f8fa`,color:`#8b949e`,border:`none`},".cm-activeLine":{backgroundColor:`#f6f8fa88`},".cm-activeLineGutter":{backgroundColor:`#eaeef2`},".cm-cursor":{borderLeftColor:`#1f2328`},"&.cm-focused .cm-selectionBackground, .cm-selectionBackground, ::selection":{backgroundColor:`#cfe3ff`}}),S(C,{fallback:!0})],I=e=>e?o.oneDark:F,L=c.of([{key:`Mod-Enter`,preventDefault:!0,run:()=>(e.onRun?.(),!0)},{key:`Shift-Enter`,preventDefault:!0,run:()=>(e.onRun?.(),!0)}]),R=e.dark,z=e.readOnly,B=e.language??[],V=t=>g.create({doc:t,extensions:[l(),d(),f(),y(),E(),p(),g.allowMultipleSelections.of(!0),w(),T(),k(),O(),m(),h(),u(),L,c.of([...A,...v,...b,...D,...j,x]),s.lineWrapping,P.of(B),M.of(I(R)),N.of(g.readOnly.of(z)),s.updateListener.of(t=>{t.docChanged&&e.onChange?.(t.state.doc.toString())})]}),H=new s({parent:e.parent,state:V(e.doc)}),U=new Map,W=e.name??``;return{fallback:!1,getCode:()=>H.state.doc.toString(),setCode(e){H.dispatch({changes:{from:0,to:H.state.doc.length,insert:e}})},openFile(e,t){if(e===W)return;U.set(W,H.state);let n=U.get(e);H.setState(n??V(t)),W=e,n&&H.dispatch({effects:[M.reconfigure(I(R)),N.reconfigure(g.readOnly.of(z)),P.reconfigure(B)]})},fileCode(e,t){if(e===W)return H.state.doc.toString();let n=U.get(e);return n?n.doc.toString():t},forgetFiles(e){for(let t of[...U.keys()])e.includes(t)||U.delete(t)},setTheme(e){R=e,H.dispatch({effects:M.reconfigure(I(R))})},setReadOnly(e){z=e,H.dispatch({effects:N.reconfigure(g.readOnly.of(z))})},setLanguage(e){B=e,H.dispatch({effects:P.reconfigure(B)})},focus:()=>H.focus(),destroy:()=>H.destroy()}}function n(e){let t=document.createElement(`textarea`);t.className=`cp-fallback-editor`,t.spellcheck=!1,t.value=e.doc,t.readOnly=e.readOnly,t.addEventListener(`input`,()=>e.onChange?.(t.value)),t.addEventListener(`keydown`,t=>{(t.metaKey||t.ctrlKey)&&t.key===`Enter`&&(t.preventDefault(),e.onRun?.())}),e.parent.appendChild(t);let n=new Map,r=e.name??``;return{fallback:!0,getCode:()=>t.value,setCode:e=>{t.value=e},openFile(e,i){e!==r&&(n.set(r,t.value),t.value=n.get(e)??i,r=e)},fileCode(e,i){return e===r?t.value:n.get(e)??i},forgetFiles(e){for(let t of[...n.keys()])e.includes(t)||n.delete(t)},setTheme:()=>{},setReadOnly:e=>{t.readOnly=e},setLanguage:()=>{},focus:()=>t.focus(),destroy:()=>t.remove()}}var r=new Map,i=new Map;function a(e,t){r.set(e,t)}function o(){return[...r.keys()]}function s(e){let t=i.get(e);if(t)return t;let n=r.get(e);if(!n)return Promise.reject(Error(`Unknown runtime "${e}". Registered: ${o().join(`, `)||`none`}`));let a=n().catch(t=>{throw i.delete(e),t});return i.set(e,a),a}a(`python`,()=>import(`./pyodide-B8qzHgzU.js`).then(e=>e.pythonRuntime)),a(`javascript`,()=>import(`./javascript-Cv8I8Gkw.js`).then(e=>e.javascriptRuntime)),a(`typescript`,()=>import(`./javascript-Cv8I8Gkw.js`).then(e=>e.typescriptRuntime));var c=class extends Error{constructor(e=`Execution stopped`){super(e),this.name=`RunStopped`}},l=class extends Error{constructor(e=`Web Workers are unavailable in this page`){super(e),this.name=`WorkerUnavailable`}},u=String.raw`
|
|
2
2
|
:host {
|
|
3
3
|
--cp-bg: #ffffff;
|
|
4
4
|
--cp-fg: #1f2328;
|
|
@@ -128,6 +128,41 @@ button.cp-danger { color: var(--cp-danger); border-color: var(--cp-danger); }
|
|
|
128
128
|
overflow: hidden;
|
|
129
129
|
}
|
|
130
130
|
.cp-editor .cm-editor { height: 100%; }
|
|
131
|
+
|
|
132
|
+
/* Content-fitting mode. Until 0.2.0 height="auto" happened to work, because a
|
|
133
|
+
percentage height against an indefinite parent computes to auto — true, but
|
|
134
|
+
accidental, and one future rule away from silently reverting to 220px. These
|
|
135
|
+
rules make it a supported mode instead. */
|
|
136
|
+
:host([height='auto']) .cp-editor,
|
|
137
|
+
:host([height='auto']) .cp-editor .cm-editor,
|
|
138
|
+
:host([height='auto']) .cp-fallback-editor {
|
|
139
|
+
height: auto;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* Bounds for that mode, following CodeMirror's own recipes.
|
|
143
|
+
|
|
144
|
+
max-height goes on .cm-editor: its theme already gives .cm-scroller
|
|
145
|
+
overflow-y: auto, so a capped editor scrolls rather than clips. Putting the
|
|
146
|
+
cap on .cp-editor instead would clip, since the scroller has already sized
|
|
147
|
+
itself to the content.
|
|
148
|
+
|
|
149
|
+
min-height goes on .cm-content and .cm-gutter, not on .cm-editor. Both give
|
|
150
|
+
the right outer height, but on .cm-editor the scroller stays at content
|
|
151
|
+
height — so the empty space below a one-line snippet is not part of the
|
|
152
|
+
editor and clicking it does nothing. That empty space is exactly what a
|
|
153
|
+
"write your answer here" box is for. */
|
|
154
|
+
.cp-editor .cm-editor { max-height: var(--cp-max-height, none); }
|
|
155
|
+
|
|
156
|
+
/* Three classes deep on purpose: CodeMirror's base theme sets
|
|
157
|
+
.cm-content { min-height: 100% } through a generated wrapper class, which
|
|
158
|
+
ties on specificity with a two-class selector and wins on order, since its
|
|
159
|
+
stylesheet is injected into the shadow root after this one. */
|
|
160
|
+
.cp-editor .cm-editor .cm-content,
|
|
161
|
+
.cp-editor .cm-editor .cm-gutter { min-height: var(--cp-min-height, 0); }
|
|
162
|
+
.cp-editor .cp-fallback-editor {
|
|
163
|
+
min-height: var(--cp-min-height, 0);
|
|
164
|
+
max-height: var(--cp-max-height, none);
|
|
165
|
+
}
|
|
131
166
|
.cp-editor .cm-scroller {
|
|
132
167
|
font-family: var(--cp-font-mono);
|
|
133
168
|
font-size: 13px;
|
|
@@ -261,10 +296,10 @@ table.cp-table th { background: var(--cp-bg); }
|
|
|
261
296
|
}
|
|
262
297
|
`,d=e=>()=>import(`@codemirror/lang-javascript`).then(t=>t.javascript(e)),f={py:()=>import(`@codemirror/lang-python`).then(e=>e.python()),pyi:()=>import(`@codemirror/lang-python`).then(e=>e.python()),js:d({}),mjs:d({}),cjs:d({}),jsx:d({jsx:!0}),ts:d({typescript:!0}),mts:d({typescript:!0}),cts:d({typescript:!0}),tsx:d({typescript:!0,jsx:!0}),json:()=>import(`@codemirror/lang-json`).then(e=>e.json())};async function p(e){let t=f[e.includes(`.`)?e.slice(e.lastIndexOf(`.`)+1).toLowerCase():``];return t?t().catch(()=>null):null}var m=`code-playpad`,h=1,g=`snippets`,_=`progress`,v=null;function y(){return typeof indexedDB>`u`?Promise.reject(Error(`IndexedDB unavailable`)):(v||=new Promise((e,t)=>{let n=indexedDB.open(m,h);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(g)||e.createObjectStore(g),e.objectStoreNames.contains(_)||e.createObjectStore(_,{keyPath:`id`})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}).catch(e=>{throw v=null,e}),v)}function b(e,t,n){return y().then(r=>new Promise((i,a)=>{let o=n(r.transaction(e,t).objectStore(e));o.onsuccess=()=>i(o.result),o.onerror=()=>a(o.error)}))}function x(e,t){return b(g,`readwrite`,n=>n.put(t,e)).then(()=>void 0)}function S(e){return b(g,`readonly`,t=>t.get(e)).then(e=>e??null)}function C(e){return b(g,`readwrite`,t=>t.delete(e)).then(()=>void 0)}function w(e,t={}){let n={completed:!0,...t,id:e,updatedAt:Date.now()};return b(_,`readwrite`,e=>e.put(n)).then(()=>n)}function T(e){return b(_,`readonly`,t=>t.get(e)).then(e=>e??null)}function E(){return b(_,`readonly`,e=>e.getAll())}var D=`code-playpad`;function O(e){let t=e.replace(/\t/g,` `).split(`
|
|
263
298
|
`);for(;t.length&&t[0].trim()===``;)t.shift();for(;t.length&&t[t.length-1].trim()===``;)t.pop();let n=t.filter(e=>e.trim()!==``).reduce((e,t)=>Math.min(e,t.match(/^ */)[0].length),1/0);return(n===1/0?t:t.map(e=>e.slice(n))).join(`
|
|
264
|
-
`)}var k=2e5,A=`playpad-file`,j={python:`main.py`,javascript:`main.js`,typescript:`main.ts`};function M(e){return j[e]??`main.txt`}function N(e,t){let n={};for(let t of e.children){if(t.tagName.toLowerCase()!==A)continue;let e=t.getAttribute(`name`);e&&(n[e]=O(t.textContent??``))}if(Object.keys(n).length)return n;let r=
|
|
299
|
+
`)}var k=2e5,A=`playpad-file`,j={python:`main.py`,javascript:`main.js`,typescript:`main.ts`};function M(e){return j[e]??`main.txt`}function N(e,t){let n={};for(let t of e.children){if(t.tagName.toLowerCase()!==A)continue;let e=t.getAttribute(`name`);e&&(n[e]=O(t.textContent??``))}if(Object.keys(n).length)return n;let r=[...e.childNodes].filter(e=>e.nodeType!==Node.ELEMENT_NODE||e.tagName.toLowerCase()!==A),i=r.some(e=>e.nodeType===Node.ELEMENT_NODE),a=O(r.filter(e=>!(i&&e.nodeType===Node.TEXT_NODE&&!(e.textContent??``).trim())).map(e=>e.textContent??``).join(``));return{[t]:a}}function P(e,t){try{let t=JSON.parse(e);if(t&&typeof t==`object`&&!Array.isArray(t)){let e=t;return Object.keys(e).length?e:null}}catch{}return e?{[t]:e}:null}var F=typeof HTMLElement>`u`?class{}:HTMLElement,I=class extends F{static get observedAttributes(){return[`language`,`height`,`min-height`,`max-height`,`theme`,`readonly`,`autorun`,`stdin`,`persist`,`entry`]}#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u=null;#d=null;#f=null;#p=null;#m={};#h={};#g=`main.py`;#_=null;#v;#y=!1;#b=!1;#x=null;#S=null;#C=()=>this.#U();#w=null;#T=!0;#E=[];#D=null;#O=null;#k=null;#A=0;#j=!1;constructor(){super(),this.#e=this.attachShadow({mode:`open`})}get code(){return this.#u?this.#u.getCode():this.#m[this.#g]??``}set code(e){this.#m[this.#g]=e,this.#L()}get files(){return this.#z()}set files(e){let t=Object.keys(e);if(!t.length)return;let n=Object.keys(this.#h);n.length===1&&!this.#h[n[0]]&&(this.#h={...e}),this.#m={...e},t.includes(this.#g)||(this.#g=this.#R()),this.#u?.forgetFiles([]),this.#L(),this.#B(),this.#I()}get entry(){return this.#R()}set entry(e){this.setAttribute(`entry`,e)}openFile(e){e in this.#m&&(this.#u&&(this.#m[this.#g]=this.#u.getCode(),this.#u.openFile(e,this.#m[e]??``)),this.#g=e,this.#B(),this.#I())}get stdin(){return this.#l?this.#l.value:``}set stdin(e){this.#l&&(this.#l.value=e,this.#c.hidden=!1)}get language(){return this.getAttribute(`language`)||`python`}set language(e){this.setAttribute(`language`,e)}getCode(){return this.code}getFiles(){return this.#z()}reset(){this.#m={...this.#h},this.#g=this.#R(),this.#u?.forgetFiles([]),this.#L(),this.#B(),this.#K(),this.#s.hidden=!0,this.#G(this.#f?.ready?`${this.#f.label} ready`:``,`idle`)}async run(){if(this.#y)return;await this.#d;let e=this.#z(),t=this.#R(),n=e[t]??``;this.#y=!0,this.#n.disabled=!0,this.#r.hidden=!1,this.#K(),this.#s.hidden=!1,this.#$(`py-run`,{code:n,entry:t,files:e,language:this.language});try{let r=await this.#F();this.#G(`Queued…`,`busy`),this.#o.hidden=!1;let i=await r.run(n,{stdin:this.#l.value,files:e,entry:t,onStart:()=>this.#G(`Running…`,`busy`),onStdout:e=>this.#q(e),onStderr:e=>this.#q(e,`cp-err`),onEcho:e=>this.#q(e,`cp-in`),onStdinRequest:()=>this.#Y()});return i.table&&this.#Q(i.table),i.value!==void 0&&this.#q(`${i.value}\n`,`cp-value`),i.hint&&this.#Z(i.hint),i.stderr?(this.#G(`Error · ${i.durationMs} ms`,`error`),this.#$(`py-error`,{message:i.stderr,hint:i.hint,language:this.language})):this.#G(`Done in ${i.durationMs} ms`,`ok`),this.#$(`py-output`,{...i,language:this.language}),i}catch(e){if(e instanceof c)this.#q(`
|
|
265
300
|
[stopped]
|
|
266
301
|
`,`cp-err`),this.#G(`Stopped`,`error`);else{let t=e instanceof Error?e.message:String(e);this.#q(t+`
|
|
267
|
-
`,`cp-err`),this.#G(`Failed to start`,`error`),this.#$(`py-error`,{message:t,language:this.language})}return}finally{this.#X(null),this.#J(),this.#y=!1,this.#n.disabled=!1,this.#r.hidden=!0,this.#o.hidden=!0}}stop(){this.#f?.stop?.()}prewarm(){return this.#F()}connectedCallback(){if(this.#j){this.#P();return}if(!this.textContent?.trim()&&document.readyState===`loading`){document.addEventListener(`DOMContentLoaded`,()=>this.isConnected&&this.#M(),{once:!0});return}this.#M()}disconnectedCallback(){this.#x?.disconnect(),this.#x=null,this.#S?.removeEventListener(`change`,this.#C),this.#S=null,this.#w&&clearTimeout(this.#w),this.#X(null),setTimeout(()=>{this.isConnected||!this.#u||(this.#_=this.#z(),this.#u.destroy(),this.#u=null,this.#d=null,this.#j=!1)},0)}attributeChangedCallback(e,t,n){if(this.#j)switch(e){case`theme`:this.#U();break;case`height`:this.#W();break;case`readonly`:this.#u?.setReadOnly(n!==null);break;case`stdin`:this.#c.hidden=n===null&&!this.#l.value;break;case`entry`:this.#B();break;case`language`:this.#f=null,this.#p=null,this.#b=!1,this.#F().catch(()=>{})}}#M(){this.#j=!0,this.#h=N(this,M(this.language)),this.#m=this.#_??{...this.#h},this.#g=this.#R(),this.#N(),this.#U(),this.#W();let t=this.getAttribute(`persist`);this.#d=(async()=>{if(t&&this.#_==null){let e=await S(t).catch(()=>null),n=e==null?null:P(e,M(this.language));if(n){let e={};for(let t of Object.keys(this.#h))e[t]=n[t]??this.#h[t];this.#m=e,this.#g=this.#R()}}this.#B();let n=await s(this.language).catch(()=>null),r=n?await n.editorLanguage().catch(()=>null):null;this.#u=await e({parent:this.#t,doc:this.#m[this.#g]??``,name:this.#g,dark:this.#H(),readOnly:this.hasAttribute(`readonly`),language:r,onRun:()=>void this.run(),onChange:e=>this.#V(e)}),this.#_=null,this.#I()})(),this.#P()}#N(){let e=document.createElement(`style`);e.textContent=u;let t=document.createElement(`div`);t.className=`cp-root`,t.innerHTML=`
|
|
302
|
+
`,`cp-err`),this.#G(`Failed to start`,`error`),this.#$(`py-error`,{message:t,language:this.language})}return}finally{this.#X(null),this.#J(),this.#y=!1,this.#n.disabled=!1,this.#r.hidden=!0,this.#o.hidden=!0}}stop(){this.#f?.stop?.()}prewarm(){return this.#F()}connectedCallback(){if(this.#j){this.#P();return}if(!this.textContent?.trim()&&document.readyState===`loading`){document.addEventListener(`DOMContentLoaded`,()=>this.isConnected&&this.#M(),{once:!0});return}this.#M()}disconnectedCallback(){this.#x?.disconnect(),this.#x=null,this.#S?.removeEventListener(`change`,this.#C),this.#S=null,this.#w&&clearTimeout(this.#w),this.#X(null),setTimeout(()=>{this.isConnected||!this.#u||(this.#_=this.#z(),this.#u.destroy(),this.#u=null,this.#d=null,this.#j=!1)},0)}attributeChangedCallback(e,t,n){if(this.#j)switch(e){case`theme`:this.#U();break;case`height`:case`min-height`:case`max-height`:this.#W();break;case`readonly`:this.#u?.setReadOnly(n!==null);break;case`stdin`:this.#c.hidden=n===null&&!this.#l.value;break;case`entry`:this.#B();break;case`language`:this.#f=null,this.#p=null,this.#b=!1,this.#F().catch(()=>{})}}#M(){this.#j=!0,this.#h=N(this,M(this.language)),this.#m=this.#_??{...this.#h},this.#g=this.#R(),this.#N(),this.#U(),this.#W();let t=this.getAttribute(`persist`);this.#d=(async()=>{if(t&&this.#_==null){let e=await S(t).catch(()=>null),n=e==null?null:P(e,M(this.language));if(n){let e={};for(let t of Object.keys(this.#h))e[t]=n[t]??this.#h[t];this.#m=e,this.#g=this.#R()}}this.#B();let n=await s(this.language).catch(()=>null),r=n?await n.editorLanguage().catch(()=>null):null;this.#u=await e({parent:this.#t,doc:this.#m[this.#g]??``,name:this.#g,dark:this.#H(),readOnly:this.hasAttribute(`readonly`),language:r,onRun:()=>void this.run(),onChange:e=>this.#V(e)}),this.#_=null,this.#I()})(),this.#P()}#N(){let e=document.createElement(`style`);e.textContent=u;let t=document.createElement(`div`);t.className=`cp-root`,t.innerHTML=`
|
|
268
303
|
<div class="cp-toolbar">
|
|
269
304
|
<button class="cp-primary" part="run-button" data-action="run">Run</button>
|
|
270
305
|
<button class="cp-danger" part="stop-button" data-action="stop" hidden>Stop</button>
|
|
@@ -280,7 +315,7 @@ table.cp-table th { background: var(--cp-bg); }
|
|
|
280
315
|
<textarea rows="2" spellcheck="false"></textarea>
|
|
281
316
|
</div>
|
|
282
317
|
<pre class="cp-output" part="output" hidden></pre>`,this.#e.replaceChildren(e,t),this.#n=t.querySelector(`[data-action="run"]`),this.#r=t.querySelector(`[data-action="stop"]`),this.#i=t.querySelector(`[data-action="reset"]`),this.#a=t.querySelector(`.cp-status`),this.#o=t.querySelector(`.cp-progress`),this.#v=t.querySelector(`.cp-tabs`),this.#t=t.querySelector(`.cp-editor`),this.#c=t.querySelector(`.cp-stdin`),this.#l=t.querySelector(`.cp-stdin textarea`),this.#s=t.querySelector(`.cp-output`),this.#c.hidden=!this.hasAttribute(`stdin`),this.#l.addEventListener(`input`,()=>this.#c.classList.remove(`cp-attention`)),this.#v.addEventListener(`click`,e=>{let t=e.target.closest(`button[data-file]`);t&&this.openFile(t.getAttribute(`data-file`))}),this.#n.addEventListener(`click`,()=>void this.run()),this.#r.addEventListener(`click`,()=>this.stop()),this.#i.addEventListener(`click`,()=>this.reset());let n=()=>void this.#F().catch(()=>{});this.#t.addEventListener(`pointerdown`,n,{once:!0}),this.#t.addEventListener(`focusin`,n,{once:!0})}#P(){this.#x||typeof IntersectionObserver>`u`||(this.#x=new IntersectionObserver(e=>{e.some(e=>e.isIntersecting)&&(this.#x?.disconnect(),this.#x=null,this.#F().then(()=>{this.hasAttribute(`autorun`)&&this.run()}).catch(()=>{}))},{rootMargin:`300px`}),this.#x.observe(this))}#F(){return this.#p||=(async()=>{let e=await s(this.language);this.#f=e,e.ready||(this.#o.hidden=!1,this.#G(`Loading ${e.label}…`,`busy`));try{await e.load(e=>{this.#y||this.#G(e.message,e.phase===`ready`?`ok`:`busy`)})}catch(e){this.#p=null,this.#G(`Runtime unavailable`,`error`);let t=e instanceof Error?e.message:String(e);throw this.#q(t+`
|
|
283
|
-
`,`cp-err`),this.#s.hidden=!1,e}finally{this.#o.hidden=!0}return this.#I(),this.#b||(this.#b=!0,this.#G(`${e.label} ready`,`ok`),this.#$(`py-ready`,{language:e.id,label:e.label})),e})(),this.#p}async#I(){if(!this.#u)return;let e=this.#g,t=await p(e);if(t){this.#g===e&&this.#u?.setLanguage(t);return}let n=e.includes(`.`)?null:await(this.#f??await s(this.language).catch(()=>null))?.editorLanguage().catch(()=>null);this.#g===e&&this.#u?.setLanguage(n??[])}#L(){if(this.#u){this.#u.setCode(this.#m[this.#g]??``);return}this.#d?.then(()=>{this.#u?.setCode(this.#m[this.#g]??``),this.#B()})}#R(){let e=Object.keys(this.#m),t=this.getAttribute(`entry`);if(t&&e.includes(t))return t;let n=M(this.language);return e.includes(n)?n:e[0]??n}#z(){let e={...this.#m};if(this.#u)for(let t of Object.keys(e))e[t]=this.#u.fileCode(t,e[t]);return e}#B(){let e=Object.keys(this.#m);if(this.#v.hidden=e.length<2,this.#v.hidden){this.#v.replaceChildren();return}let t=this.#R();this.#v.replaceChildren(...e.map(e=>{let n=document.createElement(`button`);return n.dataset.file=e,n.textContent=e,n.setAttribute(`aria-pressed`,String(e===this.#g)),e===t&&(n.classList.add(`cp-entry`),n.title=`entry point — this is the file Run executes`),n}))}#V(e){this.#m[this.#g]=e;let t=this.getAttribute(`persist`);if(!t)return;this.#w&&clearTimeout(this.#w);let n=JSON.stringify(this.#z());this.#w=setTimeout(()=>void x(t,n).catch(()=>{}),400)}#H(){let e=this.getAttribute(`theme`)??`auto`;return e===`dark`||e!==`light`&&!!this.#S?.matches}#U(){!this.#S&&typeof matchMedia==`function`&&(this.#S=matchMedia(`(prefers-color-scheme: dark)`),this.#S.addEventListener(`change`,this.#C));let e=this.#H();this.setAttribute(`data-resolved-theme`,e?`dark`:`light`),this.#u?.setTheme(e)}#W(){let
|
|
318
|
+
`,`cp-err`),this.#s.hidden=!1,e}finally{this.#o.hidden=!0}return this.#I(),this.#b||(this.#b=!0,this.#G(`${e.label} ready`,`ok`),this.#$(`py-ready`,{language:e.id,label:e.label})),e})(),this.#p}async#I(){if(!this.#u)return;let e=this.#g,t=await p(e);if(t){this.#g===e&&this.#u?.setLanguage(t);return}let n=e.includes(`.`)?null:await(this.#f??await s(this.language).catch(()=>null))?.editorLanguage().catch(()=>null);this.#g===e&&this.#u?.setLanguage(n??[])}#L(){if(this.#u){this.#u.setCode(this.#m[this.#g]??``);return}this.#d?.then(()=>{this.#u?.setCode(this.#m[this.#g]??``),this.#B()})}#R(){let e=Object.keys(this.#m),t=this.getAttribute(`entry`);if(t&&e.includes(t))return t;let n=M(this.language);return e.includes(n)?n:e[0]??n}#z(){let e={...this.#m};if(this.#u)for(let t of Object.keys(e))e[t]=this.#u.fileCode(t,e[t]);return e}#B(){let e=Object.keys(this.#m);if(this.#v.hidden=e.length<2,this.#v.hidden){this.#v.replaceChildren();return}let t=this.#R();this.#v.replaceChildren(...e.map(e=>{let n=document.createElement(`button`);return n.dataset.file=e,n.textContent=e,n.setAttribute(`aria-pressed`,String(e===this.#g)),e===t&&(n.classList.add(`cp-entry`),n.title=`entry point — this is the file Run executes`),n}))}#V(e){this.#m[this.#g]=e;let t=this.getAttribute(`persist`);if(!t)return;this.#w&&clearTimeout(this.#w);let n=JSON.stringify(this.#z());this.#w=setTimeout(()=>void x(t,n).catch(()=>{}),400)}#H(){let e=this.getAttribute(`theme`)??`auto`;return e===`dark`||e!==`light`&&!!this.#S?.matches}#U(){!this.#S&&typeof matchMedia==`function`&&(this.#S=matchMedia(`(prefers-color-scheme: dark)`),this.#S.addEventListener(`change`,this.#C));let e=this.#H();this.setAttribute(`data-resolved-theme`,e?`dark`:`light`),this.#u?.setTheme(e)}#W(){for(let[e,t]of[[`height`,`--cp-height`],[`min-height`,`--cp-min-height`],[`max-height`,`--cp-max-height`]]){let n=this.getAttribute(e);n===null||n===``?this.style.removeProperty(t):this.style.setProperty(t,/^\d+$/.test(n)?`${n}px`:n)}}#G(e,t){this.#a.textContent=e,this.#a.dataset.state=t}#K(){this.#k&&clearTimeout(this.#k),this.#k=null,this.#E=[],this.#A=0,this.#s.replaceChildren(),this.#T=!0}#q(e,t){if(!e)return;let n=t===`cp-err`&&!this.#T?`\n${e}`:e;this.#T=n.endsWith(`
|
|
284
319
|
`),this.#E.push({text:n,className:t}),this.#k??=setTimeout(()=>this.#J(),16)}#J(){if(this.#k&&clearTimeout(this.#k),this.#k=null,!this.#E.length)return;let e=this.#E;this.#E=[];let t=document.createDocumentFragment(),n=``,r,i=()=>{if(!n)return;let e=document.createElement(`span`);r&&(e.className=r),e.textContent=n,t.appendChild(e),n=``};for(let t of e){if(this.#A>=k)break;let e=t.text;this.#A+e.length>k&&(e=e.slice(0,k-this.#A)+`
|
|
285
320
|
… output truncated for display — the full text is in the py-output event
|
|
286
321
|
`),this.#A+=t.text.length,r!==t.className&&(i(),r=t.className),n+=e}i(),this.#s.hidden=!1;let a=this.#s.querySelector(`.cp-prompt`);a?this.#s.insertBefore(t,a):this.#s.appendChild(t),this.#s.scrollTop=this.#s.scrollHeight}#Y(){return this.#J(),this.#X(null),new Promise(e=>{let t=document.createElement(`form`);t.className=`cp-prompt`;let n=document.createElement(`input`);n.type=`text`,n.setAttribute(`aria-label`,`Program input — press Enter to send`),n.autocapitalize=`off`,n.autocomplete=`off`,n.spellcheck=!1;let r=document.createElement(`button`);r.type=`submit`,r.className=`cp-send`,r.textContent=`⏎`,r.title=`Send this line (Enter)`;let i=document.createElement(`button`);i.type=`button`,i.className=`cp-eof`,i.textContent=`EOF`,i.title=`End of input (Ctrl-D) — makes input() raise EOFError`;let a=n=>{this.#D===e&&(this.#D=null,this.#O=null,t.remove(),n===null?this.#q(`
|
package/dist/element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,t}from"./element-
|
|
1
|
+
import{n as e,t}from"./element-DtCQVStG.js";export{t as CodePlayPadElement,e as defineCodePlayPad};
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,c as t,d as n,f as r,i,l as a,m as o,n as s,o as c,p as l,r as u,s as d,t as f,u as p}from"./element-
|
|
1
|
+
import{a as e,c as t,d as n,f as r,i,l as a,m as o,n as s,o as c,p as l,r as u,s as d,t as f,u as p}from"./element-DtCQVStG.js";import{n as m,o as h,r as g,t as _}from"./config-DZqcFPEP.js";export{f as CodePlayPadElement,_ as PYODIDE_VERSION,a as RunStopped,p as WorkerUnavailable,u as allProgress,i as clearSnippet,m as configurePython,g as configureTypeScript,o as createEditor,s as defineCodePlayPad,e as getProgress,n as getRuntime,r as listRuntimes,c as loadSnippet,h as pyodideAssetUrls,l as registerRuntime,d as saveSnippet,t as setProgress};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as e}from"./config-DZqcFPEP.js";import{t}from"./worker-runtime-
|
|
1
|
+
import{a as e}from"./config-DZqcFPEP.js";import{t}from"./worker-runtime-HpUlPmaH.js";var n=String.raw`
|
|
2
2
|
let currentId = null;
|
|
3
3
|
let stdinLines = [];
|
|
4
4
|
let stdinExhausted = false;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{i as e}from"./config-DZqcFPEP.js";import{t}from"./worker-runtime-
|
|
1
|
+
import{i as e}from"./config-DZqcFPEP.js";import{t}from"./worker-runtime-HpUlPmaH.js";var n=`let pyodide=null,stdinLines=[],stdinExhausted=!1,currentId=null,interactive=!1,inputWaitMs=0,nextRequest=1;const pendingLines=new Map,MOUNT="/home/pyodide/playground";let written=new Set,internals=null;const REFRESH=["import importlib, os, sys","MOUNT = "+JSON.stringify(MOUNT),"os.makedirs(MOUNT, exist_ok=True)","sys.path.insert(0, MOUNT) if MOUNT not in sys.path else None","os.chdir(MOUNT)","for _name, _mod in list(sys.modules.items()):",' _file = getattr(_mod, "__file__", None) or ""',' _paths = list(getattr(_mod, "__path__", None) or [])'," if _file.startswith(MOUNT) or any(str(p).startswith(MOUNT) for p in _paths):"," del sys.modules[_name]","importlib.invalidate_caches()"].join(\`
|
|
2
2
|
\`);function flushStreams(){try{pyodide.runPython(\`import sys
|
|
3
3
|
sys.stdout.flush()
|
|
4
4
|
sys.stderr.flush()\`,{globals:internals})}catch{}flushOutput()}const INPUT_OVERRIDE=["import builtins, sys, js","from pyodide.ffi import run_sync","",'def _pg_input(prompt=""):',' if prompt != "":'," sys.stdout.write(str(prompt))"," sys.stdout.flush()"," line = run_sync(js._pgReadLine())"," # Pyodide maps JS null to its own JsNull singleton, not None, so test"," # for what we want rather than for the several ways EOF can arrive."," if not isinstance(line, str):",' raise EOFError("EOF when reading a line")'," return line","",'_pg_input.__name__ = "input"','_pg_input.__qualname__ = "input"',"_pg_input.__doc__ = builtins.input.__doc__","builtins.input = _pg_input"].join(\`
|
package/dist/react.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./element-
|
|
1
|
+
import{n as e}from"./element-DtCQVStG.js";import{useEffect as t,useRef as n}from"react";import{jsx as r}from"react/jsx-runtime";e();function i({code:e=``,files:i,entry:a,stdin:o,language:s=`python`,height:c,theme:l=`auto`,readOnly:u,autoRun:d,persist:f,className:p,style:m,onReady:h,onRun:g,onOutput:_,onError:v}){let y=n(null),b=n({onReady:h,onRun:g,onOutput:_,onError:v});b.current={onReady:h,onRun:g,onOutput:_,onError:v},t(()=>{let e=y.current;if(!e)return;let t=(t,n)=>{let r=e=>n(b.current)?.(e.detail);return e.addEventListener(t,r),()=>e.removeEventListener(t,r)},n=[t(`py-ready`,e=>e.onReady),t(`py-run`,e=>e.onRun),t(`py-output`,e=>e.onOutput),t(`py-error`,e=>e.onError)];return()=>n.forEach(e=>e())},[]);let x=i?JSON.stringify(i):null;return t(()=>{let t=y.current;t&&(x?t.files=JSON.parse(x):e!==t.code&&(t.code=e))},[e,x]),t(()=>{y.current&&o!==void 0&&(y.current.stdin=o)},[o]),r(`code-playpad`,{ref:y,language:s,theme:l,class:p,style:m,...c===void 0?{}:{height:String(c)},...u?{readonly:``}:{},...d?{autorun:``}:{},...f?{persist:f}:{},...a?{entry:a}:{},children:i?null:e})}export{i as CodePlayPad,i as default};
|
package/dist/standalone.js
CHANGED
|
@@ -133,6 +133,41 @@ button.cp-danger { color: var(--cp-danger); border-color: var(--cp-danger); }
|
|
|
133
133
|
overflow: hidden;
|
|
134
134
|
}
|
|
135
135
|
.cp-editor .cm-editor { height: 100%; }
|
|
136
|
+
|
|
137
|
+
/* Content-fitting mode. Until 0.2.0 height="auto" happened to work, because a
|
|
138
|
+
percentage height against an indefinite parent computes to auto — true, but
|
|
139
|
+
accidental, and one future rule away from silently reverting to 220px. These
|
|
140
|
+
rules make it a supported mode instead. */
|
|
141
|
+
:host([height='auto']) .cp-editor,
|
|
142
|
+
:host([height='auto']) .cp-editor .cm-editor,
|
|
143
|
+
:host([height='auto']) .cp-fallback-editor {
|
|
144
|
+
height: auto;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* Bounds for that mode, following CodeMirror's own recipes.
|
|
148
|
+
|
|
149
|
+
max-height goes on .cm-editor: its theme already gives .cm-scroller
|
|
150
|
+
overflow-y: auto, so a capped editor scrolls rather than clips. Putting the
|
|
151
|
+
cap on .cp-editor instead would clip, since the scroller has already sized
|
|
152
|
+
itself to the content.
|
|
153
|
+
|
|
154
|
+
min-height goes on .cm-content and .cm-gutter, not on .cm-editor. Both give
|
|
155
|
+
the right outer height, but on .cm-editor the scroller stays at content
|
|
156
|
+
height — so the empty space below a one-line snippet is not part of the
|
|
157
|
+
editor and clicking it does nothing. That empty space is exactly what a
|
|
158
|
+
"write your answer here" box is for. */
|
|
159
|
+
.cp-editor .cm-editor { max-height: var(--cp-max-height, none); }
|
|
160
|
+
|
|
161
|
+
/* Three classes deep on purpose: CodeMirror's base theme sets
|
|
162
|
+
.cm-content { min-height: 100% } through a generated wrapper class, which
|
|
163
|
+
ties on specificity with a two-class selector and wins on order, since its
|
|
164
|
+
stylesheet is injected into the shadow root after this one. */
|
|
165
|
+
.cp-editor .cm-editor .cm-content,
|
|
166
|
+
.cp-editor .cm-editor .cm-gutter { min-height: var(--cp-min-height, 0); }
|
|
167
|
+
.cp-editor .cp-fallback-editor {
|
|
168
|
+
min-height: var(--cp-min-height, 0);
|
|
169
|
+
max-height: var(--cp-max-height, none);
|
|
170
|
+
}
|
|
136
171
|
.cp-editor .cm-scroller {
|
|
137
172
|
font-family: var(--cp-font-mono);
|
|
138
173
|
font-size: 13px;
|
|
@@ -266,10 +301,10 @@ table.cp-table th { background: var(--cp-bg); }
|
|
|
266
301
|
}
|
|
267
302
|
`,h=e=>()=>import(`./dist-CqpVTRAq.js`).then(t=>t.javascript(e)),g={py:()=>import(`./dist-D_qJovVA.js`).then(e=>e.python()),pyi:()=>import(`./dist-D_qJovVA.js`).then(e=>e.python()),js:h({}),mjs:h({}),cjs:h({}),jsx:h({jsx:!0}),ts:h({typescript:!0}),mts:h({typescript:!0}),cts:h({typescript:!0}),tsx:h({typescript:!0,jsx:!0}),json:()=>import(`./dist-XlpaG2JF.js`).then(e=>e.json())};async function _(e){let t=g[e.includes(`.`)?e.slice(e.lastIndexOf(`.`)+1).toLowerCase():``];return t?t().catch(()=>null):null}var v=`code-playpad`,y=1,b=`snippets`,x=`progress`,S=null;function C(){return typeof indexedDB>`u`?Promise.reject(Error(`IndexedDB unavailable`)):(S||=new Promise((e,t)=>{let n=indexedDB.open(v,y);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(b)||e.createObjectStore(b),e.objectStoreNames.contains(x)||e.createObjectStore(x,{keyPath:`id`})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}).catch(e=>{throw S=null,e}),S)}function w(e,t,n){return C().then(r=>new Promise((i,a)=>{let o=n(r.transaction(e,t).objectStore(e));o.onsuccess=()=>i(o.result),o.onerror=()=>a(o.error)}))}function T(e,t){return w(b,`readwrite`,n=>n.put(t,e)).then(()=>void 0)}function E(e){return w(b,`readonly`,t=>t.get(e)).then(e=>e??null)}function D(e){return w(b,`readwrite`,t=>t.delete(e)).then(()=>void 0)}function O(e,t={}){let n={completed:!0,...t,id:e,updatedAt:Date.now()};return w(x,`readwrite`,e=>e.put(n)).then(()=>n)}function k(e){return w(x,`readonly`,t=>t.get(e)).then(e=>e??null)}function A(){return w(x,`readonly`,e=>e.getAll())}var j=`code-playpad`;function M(e){let t=e.replace(/\t/g,` `).split(`
|
|
268
303
|
`);for(;t.length&&t[0].trim()===``;)t.shift();for(;t.length&&t[t.length-1].trim()===``;)t.pop();let n=t.filter(e=>e.trim()!==``).reduce((e,t)=>Math.min(e,t.match(/^ */)[0].length),1/0);return(n===1/0?t:t.map(e=>e.slice(n))).join(`
|
|
269
|
-
`)}var N=2e5,P=`playpad-file`,F={python:`main.py`,javascript:`main.js`,typescript:`main.ts`};function I(e){return F[e]??`main.txt`}function L(e,t){let n={};for(let t of e.children){if(t.tagName.toLowerCase()!==P)continue;let e=t.getAttribute(`name`);e&&(n[e]=M(t.textContent??``))}if(Object.keys(n).length)return n;let r=
|
|
304
|
+
`)}var N=2e5,P=`playpad-file`,F={python:`main.py`,javascript:`main.js`,typescript:`main.ts`};function I(e){return F[e]??`main.txt`}function L(e,t){let n={};for(let t of e.children){if(t.tagName.toLowerCase()!==P)continue;let e=t.getAttribute(`name`);e&&(n[e]=M(t.textContent??``))}if(Object.keys(n).length)return n;let r=[...e.childNodes].filter(e=>e.nodeType!==Node.ELEMENT_NODE||e.tagName.toLowerCase()!==P),i=r.some(e=>e.nodeType===Node.ELEMENT_NODE),a=M(r.filter(e=>!(i&&e.nodeType===Node.TEXT_NODE&&!(e.textContent??``).trim())).map(e=>e.textContent??``).join(``));return{[t]:a}}function R(e,t){try{let t=JSON.parse(e);if(t&&typeof t==`object`&&!Array.isArray(t)){let e=t;return Object.keys(e).length?e:null}}catch{}return e?{[t]:e}:null}var z=typeof HTMLElement>`u`?class{}:HTMLElement,B=class extends z{static get observedAttributes(){return[`language`,`height`,`min-height`,`max-height`,`theme`,`readonly`,`autorun`,`stdin`,`persist`,`entry`]}#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u=null;#d=null;#f=null;#p=null;#m={};#h={};#g=`main.py`;#_=null;#v;#y=!1;#b=!1;#x=null;#S=null;#C=()=>this.#U();#w=null;#T=!0;#E=[];#D=null;#O=null;#k=null;#A=0;#j=!1;constructor(){super(),this.#e=this.attachShadow({mode:`open`})}get code(){return this.#u?this.#u.getCode():this.#m[this.#g]??``}set code(e){this.#m[this.#g]=e,this.#L()}get files(){return this.#z()}set files(e){let t=Object.keys(e);if(!t.length)return;let n=Object.keys(this.#h);n.length===1&&!this.#h[n[0]]&&(this.#h={...e}),this.#m={...e},t.includes(this.#g)||(this.#g=this.#R()),this.#u?.forgetFiles([]),this.#L(),this.#B(),this.#I()}get entry(){return this.#R()}set entry(e){this.setAttribute(`entry`,e)}openFile(e){e in this.#m&&(this.#u&&(this.#m[this.#g]=this.#u.getCode(),this.#u.openFile(e,this.#m[e]??``)),this.#g=e,this.#B(),this.#I())}get stdin(){return this.#l?this.#l.value:``}set stdin(e){this.#l&&(this.#l.value=e,this.#c.hidden=!1)}get language(){return this.getAttribute(`language`)||`python`}set language(e){this.setAttribute(`language`,e)}getCode(){return this.code}getFiles(){return this.#z()}reset(){this.#m={...this.#h},this.#g=this.#R(),this.#u?.forgetFiles([]),this.#L(),this.#B(),this.#K(),this.#s.hidden=!0,this.#G(this.#f?.ready?`${this.#f.label} ready`:``,`idle`)}async run(){if(this.#y)return;await this.#d;let e=this.#z(),t=this.#R(),n=e[t]??``;this.#y=!0,this.#n.disabled=!0,this.#r.hidden=!1,this.#K(),this.#s.hidden=!1,this.#$(`py-run`,{code:n,entry:t,files:e,language:this.language});try{let r=await this.#F();this.#G(`Queued…`,`busy`),this.#o.hidden=!1;let i=await r.run(n,{stdin:this.#l.value,files:e,entry:t,onStart:()=>this.#G(`Running…`,`busy`),onStdout:e=>this.#q(e),onStderr:e=>this.#q(e,`cp-err`),onEcho:e=>this.#q(e,`cp-in`),onStdinRequest:()=>this.#Y()});return i.table&&this.#Q(i.table),i.value!==void 0&&this.#q(`${i.value}\n`,`cp-value`),i.hint&&this.#Z(i.hint),i.stderr?(this.#G(`Error · ${i.durationMs} ms`,`error`),this.#$(`py-error`,{message:i.stderr,hint:i.hint,language:this.language})):this.#G(`Done in ${i.durationMs} ms`,`ok`),this.#$(`py-output`,{...i,language:this.language}),i}catch(e){if(e instanceof i)this.#q(`
|
|
270
305
|
[stopped]
|
|
271
306
|
`,`cp-err`),this.#G(`Stopped`,`error`);else{let t=e instanceof Error?e.message:String(e);this.#q(t+`
|
|
272
|
-
`,`cp-err`),this.#G(`Failed to start`,`error`),this.#$(`py-error`,{message:t,language:this.language})}return}finally{this.#X(null),this.#J(),this.#y=!1,this.#n.disabled=!1,this.#r.hidden=!0,this.#o.hidden=!0}}stop(){this.#f?.stop?.()}prewarm(){return this.#F()}connectedCallback(){if(this.#j){this.#P();return}if(!this.textContent?.trim()&&document.readyState===`loading`){document.addEventListener(`DOMContentLoaded`,()=>this.isConnected&&this.#M(),{once:!0});return}this.#M()}disconnectedCallback(){this.#x?.disconnect(),this.#x=null,this.#S?.removeEventListener(`change`,this.#C),this.#S=null,this.#w&&clearTimeout(this.#w),this.#X(null),setTimeout(()=>{this.isConnected||!this.#u||(this.#_=this.#z(),this.#u.destroy(),this.#u=null,this.#d=null,this.#j=!1)},0)}attributeChangedCallback(e,t,n){if(this.#j)switch(e){case`theme`:this.#U();break;case`height`:this.#W();break;case`readonly`:this.#u?.setReadOnly(n!==null);break;case`stdin`:this.#c.hidden=n===null&&!this.#l.value;break;case`entry`:this.#B();break;case`language`:this.#f=null,this.#p=null,this.#b=!1,this.#F().catch(()=>{})}}#M(){this.#j=!0,this.#h=L(this,I(this.language)),this.#m=this.#_??{...this.#h},this.#g=this.#R(),this.#N(),this.#U(),this.#W();let e=this.getAttribute(`persist`);this.#d=(async()=>{if(e&&this.#_==null){let t=await E(e).catch(()=>null),n=t==null?null:R(t,I(this.language));if(n){let e={};for(let t of Object.keys(this.#h))e[t]=n[t]??this.#h[t];this.#m=e,this.#g=this.#R()}}this.#B();let t=await p(this.language).catch(()=>null),n=t?await t.editorLanguage().catch(()=>null):null;this.#u=await o({parent:this.#t,doc:this.#m[this.#g]??``,name:this.#g,dark:this.#H(),readOnly:this.hasAttribute(`readonly`),language:n,onRun:()=>void this.run(),onChange:e=>this.#V(e)}),this.#_=null,this.#I()})(),this.#P()}#N(){let e=document.createElement(`style`);e.textContent=m;let t=document.createElement(`div`);t.className=`cp-root`,t.innerHTML=`
|
|
307
|
+
`,`cp-err`),this.#G(`Failed to start`,`error`),this.#$(`py-error`,{message:t,language:this.language})}return}finally{this.#X(null),this.#J(),this.#y=!1,this.#n.disabled=!1,this.#r.hidden=!0,this.#o.hidden=!0}}stop(){this.#f?.stop?.()}prewarm(){return this.#F()}connectedCallback(){if(this.#j){this.#P();return}if(!this.textContent?.trim()&&document.readyState===`loading`){document.addEventListener(`DOMContentLoaded`,()=>this.isConnected&&this.#M(),{once:!0});return}this.#M()}disconnectedCallback(){this.#x?.disconnect(),this.#x=null,this.#S?.removeEventListener(`change`,this.#C),this.#S=null,this.#w&&clearTimeout(this.#w),this.#X(null),setTimeout(()=>{this.isConnected||!this.#u||(this.#_=this.#z(),this.#u.destroy(),this.#u=null,this.#d=null,this.#j=!1)},0)}attributeChangedCallback(e,t,n){if(this.#j)switch(e){case`theme`:this.#U();break;case`height`:case`min-height`:case`max-height`:this.#W();break;case`readonly`:this.#u?.setReadOnly(n!==null);break;case`stdin`:this.#c.hidden=n===null&&!this.#l.value;break;case`entry`:this.#B();break;case`language`:this.#f=null,this.#p=null,this.#b=!1,this.#F().catch(()=>{})}}#M(){this.#j=!0,this.#h=L(this,I(this.language)),this.#m=this.#_??{...this.#h},this.#g=this.#R(),this.#N(),this.#U(),this.#W();let e=this.getAttribute(`persist`);this.#d=(async()=>{if(e&&this.#_==null){let t=await E(e).catch(()=>null),n=t==null?null:R(t,I(this.language));if(n){let e={};for(let t of Object.keys(this.#h))e[t]=n[t]??this.#h[t];this.#m=e,this.#g=this.#R()}}this.#B();let t=await p(this.language).catch(()=>null),n=t?await t.editorLanguage().catch(()=>null):null;this.#u=await o({parent:this.#t,doc:this.#m[this.#g]??``,name:this.#g,dark:this.#H(),readOnly:this.hasAttribute(`readonly`),language:n,onRun:()=>void this.run(),onChange:e=>this.#V(e)}),this.#_=null,this.#I()})(),this.#P()}#N(){let e=document.createElement(`style`);e.textContent=m;let t=document.createElement(`div`);t.className=`cp-root`,t.innerHTML=`
|
|
273
308
|
<div class="cp-toolbar">
|
|
274
309
|
<button class="cp-primary" part="run-button" data-action="run">Run</button>
|
|
275
310
|
<button class="cp-danger" part="stop-button" data-action="stop" hidden>Stop</button>
|
|
@@ -285,7 +320,7 @@ table.cp-table th { background: var(--cp-bg); }
|
|
|
285
320
|
<textarea rows="2" spellcheck="false"></textarea>
|
|
286
321
|
</div>
|
|
287
322
|
<pre class="cp-output" part="output" hidden></pre>`,this.#e.replaceChildren(e,t),this.#n=t.querySelector(`[data-action="run"]`),this.#r=t.querySelector(`[data-action="stop"]`),this.#i=t.querySelector(`[data-action="reset"]`),this.#a=t.querySelector(`.cp-status`),this.#o=t.querySelector(`.cp-progress`),this.#v=t.querySelector(`.cp-tabs`),this.#t=t.querySelector(`.cp-editor`),this.#c=t.querySelector(`.cp-stdin`),this.#l=t.querySelector(`.cp-stdin textarea`),this.#s=t.querySelector(`.cp-output`),this.#c.hidden=!this.hasAttribute(`stdin`),this.#l.addEventListener(`input`,()=>this.#c.classList.remove(`cp-attention`)),this.#v.addEventListener(`click`,e=>{let t=e.target.closest(`button[data-file]`);t&&this.openFile(t.getAttribute(`data-file`))}),this.#n.addEventListener(`click`,()=>void this.run()),this.#r.addEventListener(`click`,()=>this.stop()),this.#i.addEventListener(`click`,()=>this.reset());let n=()=>void this.#F().catch(()=>{});this.#t.addEventListener(`pointerdown`,n,{once:!0}),this.#t.addEventListener(`focusin`,n,{once:!0})}#P(){this.#x||typeof IntersectionObserver>`u`||(this.#x=new IntersectionObserver(e=>{e.some(e=>e.isIntersecting)&&(this.#x?.disconnect(),this.#x=null,this.#F().then(()=>{this.hasAttribute(`autorun`)&&this.run()}).catch(()=>{}))},{rootMargin:`300px`}),this.#x.observe(this))}#F(){return this.#p||=(async()=>{let e=await p(this.language);this.#f=e,e.ready||(this.#o.hidden=!1,this.#G(`Loading ${e.label}…`,`busy`));try{await e.load(e=>{this.#y||this.#G(e.message,e.phase===`ready`?`ok`:`busy`)})}catch(e){this.#p=null,this.#G(`Runtime unavailable`,`error`);let t=e instanceof Error?e.message:String(e);throw this.#q(t+`
|
|
288
|
-
`,`cp-err`),this.#s.hidden=!1,e}finally{this.#o.hidden=!0}return this.#I(),this.#b||(this.#b=!0,this.#G(`${e.label} ready`,`ok`),this.#$(`py-ready`,{language:e.id,label:e.label})),e})(),this.#p}async#I(){if(!this.#u)return;let e=this.#g,t=await _(e);if(t){this.#g===e&&this.#u?.setLanguage(t);return}let n=e.includes(`.`)?null:await(this.#f??await p(this.language).catch(()=>null))?.editorLanguage().catch(()=>null);this.#g===e&&this.#u?.setLanguage(n??[])}#L(){if(this.#u){this.#u.setCode(this.#m[this.#g]??``);return}this.#d?.then(()=>{this.#u?.setCode(this.#m[this.#g]??``),this.#B()})}#R(){let e=Object.keys(this.#m),t=this.getAttribute(`entry`);if(t&&e.includes(t))return t;let n=I(this.language);return e.includes(n)?n:e[0]??n}#z(){let e={...this.#m};if(this.#u)for(let t of Object.keys(e))e[t]=this.#u.fileCode(t,e[t]);return e}#B(){let e=Object.keys(this.#m);if(this.#v.hidden=e.length<2,this.#v.hidden){this.#v.replaceChildren();return}let t=this.#R();this.#v.replaceChildren(...e.map(e=>{let n=document.createElement(`button`);return n.dataset.file=e,n.textContent=e,n.setAttribute(`aria-pressed`,String(e===this.#g)),e===t&&(n.classList.add(`cp-entry`),n.title=`entry point — this is the file Run executes`),n}))}#V(e){this.#m[this.#g]=e;let t=this.getAttribute(`persist`);if(!t)return;this.#w&&clearTimeout(this.#w);let n=JSON.stringify(this.#z());this.#w=setTimeout(()=>void T(t,n).catch(()=>{}),400)}#H(){let e=this.getAttribute(`theme`)??`auto`;return e===`dark`||e!==`light`&&!!this.#S?.matches}#U(){!this.#S&&typeof matchMedia==`function`&&(this.#S=matchMedia(`(prefers-color-scheme: dark)`),this.#S.addEventListener(`change`,this.#C));let e=this.#H();this.setAttribute(`data-resolved-theme`,e?`dark`:`light`),this.#u?.setTheme(e)}#W(){let
|
|
323
|
+
`,`cp-err`),this.#s.hidden=!1,e}finally{this.#o.hidden=!0}return this.#I(),this.#b||(this.#b=!0,this.#G(`${e.label} ready`,`ok`),this.#$(`py-ready`,{language:e.id,label:e.label})),e})(),this.#p}async#I(){if(!this.#u)return;let e=this.#g,t=await _(e);if(t){this.#g===e&&this.#u?.setLanguage(t);return}let n=e.includes(`.`)?null:await(this.#f??await p(this.language).catch(()=>null))?.editorLanguage().catch(()=>null);this.#g===e&&this.#u?.setLanguage(n??[])}#L(){if(this.#u){this.#u.setCode(this.#m[this.#g]??``);return}this.#d?.then(()=>{this.#u?.setCode(this.#m[this.#g]??``),this.#B()})}#R(){let e=Object.keys(this.#m),t=this.getAttribute(`entry`);if(t&&e.includes(t))return t;let n=I(this.language);return e.includes(n)?n:e[0]??n}#z(){let e={...this.#m};if(this.#u)for(let t of Object.keys(e))e[t]=this.#u.fileCode(t,e[t]);return e}#B(){let e=Object.keys(this.#m);if(this.#v.hidden=e.length<2,this.#v.hidden){this.#v.replaceChildren();return}let t=this.#R();this.#v.replaceChildren(...e.map(e=>{let n=document.createElement(`button`);return n.dataset.file=e,n.textContent=e,n.setAttribute(`aria-pressed`,String(e===this.#g)),e===t&&(n.classList.add(`cp-entry`),n.title=`entry point — this is the file Run executes`),n}))}#V(e){this.#m[this.#g]=e;let t=this.getAttribute(`persist`);if(!t)return;this.#w&&clearTimeout(this.#w);let n=JSON.stringify(this.#z());this.#w=setTimeout(()=>void T(t,n).catch(()=>{}),400)}#H(){let e=this.getAttribute(`theme`)??`auto`;return e===`dark`||e!==`light`&&!!this.#S?.matches}#U(){!this.#S&&typeof matchMedia==`function`&&(this.#S=matchMedia(`(prefers-color-scheme: dark)`),this.#S.addEventListener(`change`,this.#C));let e=this.#H();this.setAttribute(`data-resolved-theme`,e?`dark`:`light`),this.#u?.setTheme(e)}#W(){for(let[e,t]of[[`height`,`--cp-height`],[`min-height`,`--cp-min-height`],[`max-height`,`--cp-max-height`]]){let n=this.getAttribute(e);n===null||n===``?this.style.removeProperty(t):this.style.setProperty(t,/^\d+$/.test(n)?`${n}px`:n)}}#G(e,t){this.#a.textContent=e,this.#a.dataset.state=t}#K(){this.#k&&clearTimeout(this.#k),this.#k=null,this.#E=[],this.#A=0,this.#s.replaceChildren(),this.#T=!0}#q(e,t){if(!e)return;let n=t===`cp-err`&&!this.#T?`\n${e}`:e;this.#T=n.endsWith(`
|
|
289
324
|
`),this.#E.push({text:n,className:t}),this.#k??=setTimeout(()=>this.#J(),16)}#J(){if(this.#k&&clearTimeout(this.#k),this.#k=null,!this.#E.length)return;let e=this.#E;this.#E=[];let t=document.createDocumentFragment(),n=``,r,i=()=>{if(!n)return;let e=document.createElement(`span`);r&&(e.className=r),e.textContent=n,t.appendChild(e),n=``};for(let t of e){if(this.#A>=N)break;let e=t.text;this.#A+e.length>N&&(e=e.slice(0,N-this.#A)+`
|
|
290
325
|
… output truncated for display — the full text is in the py-output event
|
|
291
326
|
`),this.#A+=t.text.length,r!==t.className&&(i(),r=t.className),n+=e}i(),this.#s.hidden=!1;let a=this.#s.querySelector(`.cp-prompt`);a?this.#s.insertBefore(t,a):this.#s.appendChild(t),this.#s.scrollTop=this.#s.scrollHeight}#Y(){return this.#J(),this.#X(null),new Promise(e=>{let t=document.createElement(`form`);t.className=`cp-prompt`;let n=document.createElement(`input`);n.type=`text`,n.setAttribute(`aria-label`,`Program input — press Enter to send`),n.autocapitalize=`off`,n.autocomplete=`off`,n.spellcheck=!1;let r=document.createElement(`button`);r.type=`submit`,r.className=`cp-send`,r.textContent=`⏎`,r.title=`Send this line (Enter)`;let i=document.createElement(`button`);i.type=`button`,i.className=`cp-eof`,i.textContent=`EOF`,i.title=`End of input (Ctrl-D) — makes input() raise EOFError`;let a=n=>{this.#D===e&&(this.#D=null,this.#O=null,t.remove(),n===null?this.#q(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{l as e,u as t}from"./element-
|
|
1
|
+
import{l as e,u as t}from"./element-DtCQVStG.js";var n=1,r=class{#e=null;#t=null;#n=`module`;#r=null;#i=!1;#a=!1;#o=``;#s=new Set;#c=[];#l=null;#u=!1;initPayload(){return{}}get ready(){return this.#i}get interactiveStdin(){return this.#a}get version(){return this.#o}load(e){e&&this.#s.add(e);let n=()=>{e&&this.#s.delete(e)};if(!this.#r){let e=new Promise((e,n)=>{let r;try{if(typeof Worker>`u`)throw Error(`Worker constructor missing`);let e=new Blob([this.source],{type:`text/javascript`});this.#t=URL.createObjectURL(e),r=new Worker(this.#t,{type:this.#n})}catch(e){n(new t(`Could not start a Web Worker: ${e.message}`));return}this.#e=r,r.onmessage=t=>{let r=t.data;if(r.type===`ready`){this.#o=r.version,this.#a=r.interactiveStdin===!0,this.#i=!0,this.#p({phase:`ready`,message:`${this.label} ready`}),e();return}if(r.type===`fatal`&&!this.#i){this.#d(r.message,e,n);return}this.#m(r)},r.onerror=t=>{let r=t.message||`Worker failed to start`;this.#i?this.#l&&this.#g(this.#l,Error(r)):this.#d(r,e,n)},r.postMessage({type:`init`,...this.initPayload()})});this.#r=e,e.catch(()=>{this.#r===e&&(this.#r=null)})}return this.#r.then(n,e=>{throw n(),e})}run(e,t={}){let r,i=new Promise(e=>{r=e});return new Promise((a,o)=>{this.#c.push({id:n++,code:e,options:t,stdout:``,stderr:``,resolve:a,reject:o,done:i,markDone:r}),this.#_()})}stop(){let t=this.#e!==null;this.#f(),this.#l&&this.#g(this.#l,new e),t&&this.load().catch(()=>{})}#d(e,t,n){if(this.#f(),this.#n===`module`){this.#n=`classic`,this.load().then(t,n);return}n(Error(e))}#f(){this.#e?.terminate(),this.#e=null,this.#t&&=(URL.revokeObjectURL(this.#t),null),this.#r=null,this.#i=!1}#p(e){for(let t of this.#s)t(e)}#m(e){if(e.type===`progress`){this.#p({phase:e.phase,message:e.message});return}let t=this.#l;if(!(!t||!(`id`in e)||e.id!==t.id))switch(e.type){case`stdout`:t.stdout+=e.text,t.options.onStdout?.(e.text);break;case`echo`:t.options.onEcho?.(e.text);break;case`stdin-request`:this.#h(t,e.request);break;case`stderr`:t.stderr+=e.text,t.options.onStderr?.(e.text);break;case`result`:t.resolve({stdout:t.stdout,stderr:t.stderr||void 0,value:e.value,durationMs:Math.round(e.durationMs)}),t.markDone();break;case`error`:case`fatal`:{let n=(t.stderr&&!t.stderr.endsWith(`
|
|
2
2
|
`)?`
|
|
3
3
|
`:``)+e.message+`
|
|
4
4
|
`;t.stderr+=n,t.options.onStderr?.(n),t.resolve({stdout:t.stdout,stderr:t.stderr,hint:`hint`in e?e.hint:void 0,durationMs:Math.round(`durationMs`in e?e.durationMs:0)}),t.markDone();break}}}#h(e,t){let n=this.#e,r=r=>{this.#e===n&&this.#l===e&&n?.postMessage({type:`stdin-response`,request:t,text:r})},i=e.options.onStdinRequest;if(!i){r(null);return}i().then(r,()=>r(null))}#g(e,t){e.reject(t),e.markDone()}async#_(){if(!this.#u){this.#u=!0;try{for(;this.#c.length;){let e=this.#c.shift();this.#l=e;try{await this.load(),e.options.onStart?.(),this.#e.postMessage({type:`run`,id:e.id,code:e.code,stdin:e.options.stdin,files:e.options.files,entry:e.options.entry}),await e.done}catch(t){this.#g(e,t)}finally{this.#l=null}}}finally{this.#u=!1}}}};export{r as t};
|
package/package.json
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-playpad",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Embeddable browser code playground: a CodeMirror editor that runs Python, JavaScript and TypeScript in the browser. No backend. One shared worker per page, blocking input(), multi-file projects, lazy per-language loading.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"sideEffects": [
|
|
8
|
-
"./dist
|
|
9
|
-
"./dist/index.js",
|
|
10
|
-
"./dist/standalone.js"
|
|
8
|
+
"./dist/*.js"
|
|
11
9
|
],
|
|
12
10
|
"files": [
|
|
13
11
|
"dist",
|
|
@@ -78,6 +76,7 @@
|
|
|
78
76
|
"@codemirror/view": "^6.43.9",
|
|
79
77
|
"@types/react": "^19.2.18",
|
|
80
78
|
"@types/react-dom": "^19.2.4",
|
|
79
|
+
"@vercel/analytics": "^2.0.1",
|
|
81
80
|
"esbuild": "^0.28.2",
|
|
82
81
|
"react": "^19.2.8",
|
|
83
82
|
"react-dom": "^19.2.8",
|