code-playpad 0.10.1 → 0.12.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 +222 -17
- package/dist/THIRD-PARTY-NOTICES.txt +223 -0
- package/dist/cdn.js +2 -2
- package/dist/compiler-B408qd3N.js +151 -0
- package/dist/{config-CT3H6Oum.js → config-DB58UVsk.js} +1 -1
- package/dist/{cpp-Cs32J8JC.js → cpp-Bhr_Zgfk.js} +1 -1
- package/dist/{cpp-CO2abWii.js → cpp-xLJOrOXX.js} +1 -1
- package/dist/dist-3xj9-ylK.js +6 -0
- package/dist/{dist-BIgiGgKu.js → dist-7CHy0evE.js} +1 -1
- package/dist/dist-BDifu2bQ.js +6 -0
- package/dist/dist-BwlTZqCY.js +28 -0
- package/dist/dist-C41hAfPr.js +6 -0
- package/dist/dist-CRXZcpYD.js +14 -0
- package/dist/dist-CTLX4tws.js +8 -0
- package/dist/dist-CjnVq6q1.js +10 -0
- package/dist/{dist-Vr-fb58P.js → dist-D4P7t1AU.js} +4 -4
- package/dist/dist-DHeVjdBc.js +6 -0
- package/dist/dist-IFh_mUXG.js +7 -0
- package/dist/dist-UbI3_a5S.js +6 -0
- package/dist/dist-_fde-E8H.js +6 -0
- package/dist/dist-g8djAEMH.js +6 -0
- package/dist/dist-ixcYRC9x.js +6 -0
- package/dist/editor.d.ts +3 -1
- package/dist/element-Dzhksh6_.js +596 -0
- package/dist/element.d.ts +26 -0
- package/dist/element.js +1 -1
- package/dist/hints-DpBIeoeG.js +6 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +1 -1
- package/dist/{java-8qjVCjsN.js → java-DFiOVxDN.js} +1 -1
- package/dist/{java-DeBiVPXO.js → java-DjuG1fCk.js} +1 -1
- package/dist/{javascript-DLPaJJzf.js → javascript-BBiCDtZ3.js} +2 -2
- package/dist/{javascript-B1tVx7AD.js → javascript-CLaHCZ8o.js} +1 -1
- package/dist/languages.d.ts +1 -1
- package/dist/{pyodide-C8ImkXdD.js → pyodide-Cs-Kwccb.js} +1 -1
- package/dist/{pyodide-BOoYEfX1.js → pyodide-QurAOd7j.js} +2 -2
- package/dist/react-ALhWeEZ5.js +9 -0
- package/dist/react-DmuIc3qw.js +4 -0
- package/dist/react-runtime-19.2.8.js +240 -0
- package/dist/react-vendor.generated-DMxIoCMn.js +6 -0
- package/dist/react-version.generated-BNNJmf7J.js +6 -0
- package/dist/react.d.ts +9 -1
- package/dist/react.js +1 -1
- package/dist/rolldown-runtime-DK3Fl9T5.js +6 -0
- package/dist/runtime/config.d.ts +15 -1
- package/dist/runtime/react/boot.d.ts +9 -0
- package/dist/runtime/react/compiler.d.ts +30 -0
- package/dist/runtime/react-vendor.generated.d.ts +5 -0
- package/dist/runtime/react-version.generated.d.ts +3 -0
- package/dist/runtime/react.d.ts +2 -0
- package/dist/standalone.js +289 -17
- package/dist/styles.d.ts +0 -2
- package/dist/theme.d.ts +48 -0
- package/dist/{hints-CCMgezw9.js → types-CfcYqU2K.js} +1 -1
- package/dist/types.d.ts +23 -0
- package/dist/worker-runtime-DvpugeXD.js +9 -0
- package/dist/{worker-runtime-sUPz1J56.js → worker-runtime-tSXm-pPB.js} +1 -1
- package/package.json +23 -6
- package/dist/dist--J_vhCIU.js +0 -14
- package/dist/dist-BNvM_BAY.js +0 -6
- package/dist/dist-BkpKCrXQ.js +0 -6
- package/dist/dist-CJxiVI4a.js +0 -6
- package/dist/dist-CNOK8CHE.js +0 -6
- package/dist/dist-D25hs99E.js +0 -10
- package/dist/dist-D2igTc4m.js +0 -6
- package/dist/dist-D7jBL3Ib.js +0 -28
- package/dist/dist-DXjodKfp.js +0 -6
- package/dist/dist-DfFrsBkU.js +0 -8
- package/dist/element-CQGYVEF7.js +0 -324
- package/dist/worker-runtime-DfYet3xy.js +0 -9
package/dist/react.d.ts
CHANGED
|
@@ -16,7 +16,15 @@ export interface CodePlayPadProps {
|
|
|
16
16
|
/** Bounds for `height="auto"`. A number means pixels. */
|
|
17
17
|
minHeight?: number | string;
|
|
18
18
|
maxHeight?: number | string;
|
|
19
|
+
/** language="react": the preview's height. A number means pixels. */
|
|
20
|
+
previewHeight?: number | string;
|
|
21
|
+
/** How to list several files: "tabs" (default) or "tree". */
|
|
22
|
+
fileView?: 'tabs' | 'tree';
|
|
23
|
+
/** Which file is on screen to begin with, if not the entry. */
|
|
24
|
+
openFile?: string;
|
|
19
25
|
theme?: 'light' | 'dark' | 'auto';
|
|
26
|
+
/** false hides the theme button and editor theme list. */
|
|
27
|
+
themeControls?: boolean;
|
|
20
28
|
readOnly?: boolean;
|
|
21
29
|
autoRun?: boolean;
|
|
22
30
|
/** IndexedDB key: edits are restored on the student's next visit */
|
|
@@ -38,7 +46,7 @@ export interface CodePlayPadProps {
|
|
|
38
46
|
* which keeps React 18 (no non-string prop support on custom elements) working
|
|
39
47
|
* the same as React 19.
|
|
40
48
|
*/
|
|
41
|
-
export declare function CodePlayPad({ code, files, entry, stdin, language, height, minHeight, maxHeight, theme, readOnly, autoRun, persist, practice, className, style, onReady, onRun, onOutput, onError }: CodePlayPadProps): import("react").JSX.Element;
|
|
49
|
+
export declare function CodePlayPad({ code, files, entry, stdin, language, height, minHeight, maxHeight, previewHeight, fileView, openFile, theme, themeControls, readOnly, autoRun, persist, practice, className, style, onReady, onRun, onOutput, onError }: CodePlayPadProps): import("react").JSX.Element;
|
|
42
50
|
declare module 'react' {
|
|
43
51
|
namespace JSX {
|
|
44
52
|
interface IntrinsicElements {
|
package/dist/react.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./element-
|
|
1
|
+
import{n as e}from"./element-Dzhksh6_.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,minHeight:l,maxHeight:u,previewHeight:d,fileView:f,openFile:p,theme:m=`auto`,themeControls:h=!0,readOnly:g,autoRun:_,persist:v,practice:y,className:b,style:x,onReady:S,onRun:C,onOutput:w,onError:T}){let E=n(null),D=n({onReady:S,onRun:C,onOutput:w,onError:T});D.current={onReady:S,onRun:C,onOutput:w,onError:T},t(()=>{let e=E.current;if(!e)return;let t=(t,n)=>{let r=e=>n(D.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 O=i?JSON.stringify(i):null;t(()=>{let t=E.current;t&&(O?t.files=JSON.parse(O):e!==t.code&&(t.code=e))},[e,O]),t(()=>{E.current&&o!==void 0&&(E.current.stdin=o)},[o]);let k=y?JSON.stringify(y):null;return t(()=>{E.current&&(E.current.practice=k?JSON.parse(k):null)},[k]),/* @__PURE__ */ r(`code-playpad`,{ref:E,language:s,theme:m,"theme-controls":h?void 0:`off`,class:b,style:x,...c===void 0?{}:{height:String(c)},...l===void 0?{}:{"min-height":String(l)},...u===void 0?{}:{"max-height":String(u)},...d===void 0?{}:{"preview-height":String(d)},...f?{"file-view":f}:{},...p?{"open-file":p}:{},...g?{readonly:``}:{},..._?{autorun:``}:{},...v?{persist:v}:{},...a?{entry:a}:{},children:i?null:e})}export{i as CodePlayPad,i as default};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* code-playpad — MIT © 2026 Seung Hun Lee
|
|
3
|
+
* Bundles CodeMirror 6 and Lezer (MIT) © Marijn Haverbeke and others.
|
|
4
|
+
* Full third-party licences: THIRD-PARTY-NOTICES.txt in this package.
|
|
5
|
+
*/
|
|
6
|
+
var e=Object.defineProperty,t=(t,n)=>{let r={};for(var i in t)e(r,i,{get:t[i],enumerable:!0});return n||e(r,Symbol.toStringTag,{value:`Module`}),r};export{t};
|
package/dist/runtime/config.d.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* every page would download it — including pages that only run JavaScript.
|
|
7
7
|
* This module holds nothing but a few strings.
|
|
8
8
|
*/
|
|
9
|
+
import { REACT_VERSION } from './react-version.generated.js';
|
|
9
10
|
/** Pinned so the CDN response is cacheable forever. */
|
|
10
11
|
export declare const PYODIDE_VERSION = "314.0.5";
|
|
11
12
|
/** Point Python at your own origin — strongly recommended in production, so you
|
|
@@ -42,4 +43,17 @@ export declare function configureCpp(options: {
|
|
|
42
43
|
timeoutMs?: number;
|
|
43
44
|
}): void;
|
|
44
45
|
export declare function getCppConfig(): Readonly<typeof cppConfig>;
|
|
45
|
-
export {};
|
|
46
|
+
export { REACT_VERSION };
|
|
47
|
+
/** React previews need no configuration. `runtimeURL` loads React in the frame
|
|
48
|
+
* from a URL of your own (`dist/react-runtime-<version>.js`) instead of sending
|
|
49
|
+
* it from the page. `nonce` is for host pages whose Content-Security-Policy
|
|
50
|
+
* forbids inline scripts or styles; by default it is read from the page's first
|
|
51
|
+
* `<script nonce>`. Call before a widget runs. */
|
|
52
|
+
export declare function configureReact(options: {
|
|
53
|
+
runtimeURL?: string;
|
|
54
|
+
nonce?: string;
|
|
55
|
+
}): void;
|
|
56
|
+
export declare function getReactConfig(): {
|
|
57
|
+
runtimeURL: string | null;
|
|
58
|
+
nonce: string | null;
|
|
59
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one script written into the preview document. It runs first, wires the
|
|
3
|
+
* frame to the widget, and waits for the project: the code arrives over a port
|
|
4
|
+
* this script hands to its parent, and runs from created <script> elements, so
|
|
5
|
+
* the HTML parser never sees learner code and nothing in it needs escaping. A
|
|
6
|
+
* port rather than checking event.source, because a widget in a separate window
|
|
7
|
+
* is run by the opening page's script, which is then the sender.
|
|
8
|
+
*/
|
|
9
|
+
export declare const REACT_BOOT_SOURCE: string;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React projects as modules for the preview frame. Every file is parsed by
|
|
3
|
+
* acorn-jsx first: Sucrase accepts mismatched tags and can blame the wrong line
|
|
4
|
+
* for arrow components. The AST also gives the import list and the places for
|
|
5
|
+
* loop guards.
|
|
6
|
+
*/
|
|
7
|
+
/** Packages a project can import. The vendor bundle defines exactly these. */
|
|
8
|
+
export declare const REACT_PACKAGES: string[];
|
|
9
|
+
/** What the loop guard is called inside compiled code; the boot script defines it. */
|
|
10
|
+
export declare const LOOP_GUARD = "__playpadLoopGuard";
|
|
11
|
+
export interface CompiledModule {
|
|
12
|
+
path: string;
|
|
13
|
+
kind: 'js' | 'css' | 'json';
|
|
14
|
+
text: string;
|
|
15
|
+
/** Import specifier -> project file. Packages come from the vendor bundle. */
|
|
16
|
+
links: Record<string, string>;
|
|
17
|
+
}
|
|
18
|
+
/** A problem with the learner's project, reported against one of its files. */
|
|
19
|
+
export declare class CompileError extends Error {
|
|
20
|
+
readonly file: string;
|
|
21
|
+
readonly reason: string;
|
|
22
|
+
readonly line?: number | undefined;
|
|
23
|
+
readonly column?: number | undefined;
|
|
24
|
+
readonly hint?: string | undefined;
|
|
25
|
+
constructor(file: string, reason: string, line?: number | undefined, column?: number | undefined, hint?: string | undefined);
|
|
26
|
+
}
|
|
27
|
+
/** Resolve an import as Vite does: against the importing file, trying the extensions a learner may leave off. */
|
|
28
|
+
export declare function resolveImport(files: Record<string, string>, from: string, spec: string): string | undefined;
|
|
29
|
+
/** Compile the entry files and everything they import. A file nothing imports is not compiled, as in Vite. */
|
|
30
|
+
export declare function compileProject(files: Record<string, string>, entries: string[]): CompiledModule[];
|
package/dist/standalone.js
CHANGED
|
@@ -3,7 +3,19 @@
|
|
|
3
3
|
* Bundles CodeMirror 6 and Lezer (MIT) © Marijn Haverbeke and others.
|
|
4
4
|
* Full third-party licences: THIRD-PARTY-NOTICES.txt in this package.
|
|
5
5
|
*/
|
|
6
|
-
import{n as e,
|
|
6
|
+
import{n as e,t}from"./types-CfcYqU2K.js";import{t as n}from"./hints-DpBIeoeG.js";import{t as r}from"./react-version.generated-BNNJmf7J.js";import{a as i,i as a,n as o,r as s,t as c,u as l}from"./config-DB58UVsk.js";var u=[{id:`default-dark`,label:`One Dark`,mode:`dark`},{id:`monokai`,label:`Monokai`,mode:`dark`,colors:{bg:`#272822`,fg:`#f8f8f2`,muted:`#b4b19c`,surface:`#1e1f1a`,border:`#49483e`,accent:`#a6e22e`,accentFg:`#1e1f1a`,danger:`#ff6188`,ok:`#a6e22e`,selection:`#49483e`,activeLine:`#3e3d3266`,comment:`#a09b80`,keyword:`#ff5c94`,string:`#e6db74`,number:`#ae81ff`,fn:`#a6e22e`,type:`#66d9ef`,variable:`#f8f8f2`}},{id:`dracula`,label:`Dracula`,mode:`dark`,colors:{bg:`#282a36`,fg:`#f8f8f2`,muted:`#b6bcd6`,surface:`#21222c`,border:`#44475a`,accent:`#bd93f9`,accentFg:`#21222c`,danger:`#ff5555`,ok:`#50fa7b`,selection:`#44475a`,activeLine:`#44475a55`,comment:`#9aa5ce`,keyword:`#ff79c6`,string:`#f1fa8c`,number:`#bd93f9`,fn:`#50fa7b`,type:`#8be9fd`,variable:`#f8f8f2`}},{id:`nord`,label:`Nord`,mode:`dark`,colors:{bg:`#2e3440`,fg:`#d8dee9`,muted:`#b0b9c9`,surface:`#272c36`,border:`#434c5e`,accent:`#88c0d0`,accentFg:`#272c36`,danger:`#e08a91`,ok:`#a3be8c`,selection:`#434c5e`,activeLine:`#3b425266`,comment:`#a0abbf`,keyword:`#81a1c1`,string:`#a3be8c`,number:`#bd98b6`,fn:`#88c0d0`,type:`#8fbcbb`,variable:`#d8dee9`}},{id:`solarized-dark`,label:`Solarized Dark`,mode:`dark`,colors:{bg:`#002b36`,fg:`#c5d3d3`,muted:`#9fb0b0`,surface:`#00222b`,border:`#17505e`,accent:`#2aa198`,accentFg:`#00222b`,danger:`#f0746f`,ok:`#a3b300`,selection:`#17505e`,activeLine:`#073642aa`,comment:`#8fa3a8`,keyword:`#a3b300`,string:`#2aa198`,number:`#e87f7c`,fn:`#4ba3e3`,type:`#d6a100`,variable:`#c5d3d3`}},{id:`default-light`,label:`Default Light`,mode:`light`},{id:`github-light`,label:`GitHub Light`,mode:`light`,colors:{bg:`#ffffff`,fg:`#24292f`,muted:`#59636e`,surface:`#f6f8fa`,border:`#d1d9e0`,accent:`#0969da`,accentFg:`#ffffff`,danger:`#cf222e`,ok:`#1a7f37`,selection:`#b6d7ff`,activeLine:`#eaeef266`,comment:`#59636e`,keyword:`#cf222e`,string:`#0a3069`,number:`#0550ae`,fn:`#8250df`,type:`#953800`,variable:`#24292f`}},{id:`solarized-light`,label:`Solarized Light`,mode:`light`,colors:{bg:`#fdf6e3`,fg:`#47565c`,muted:`#566569`,surface:`#eee8d5`,border:`#d6cfb8`,accent:`#1f6fa8`,accentFg:`#ffffff`,danger:`#c0302c`,ok:`#5f6f00`,selection:`#e3dcc4`,activeLine:`#eee8d588`,comment:`#5c6c70`,keyword:`#5f6f00`,string:`#1a7a73`,number:`#c0302c`,fn:`#1f6fa8`,type:`#8f6a00`,variable:`#47565c`}}],d=`code-playpad:theme`,f=`playpad-theme-change`,p={mode:null,light:`default-light`,dark:`default-dark`},m=null,h=!1;function g(e,t){return u.some(n=>n.id===e&&n.mode===t)?e:p[t]}function _(){let e=m;if(!e)try{e=JSON.parse(localStorage.getItem(d)??`null`)}catch{}return{mode:e?.mode===`light`||e?.mode===`dark`?e.mode:null,light:g(e?.light,`light`),dark:g(e?.dark,`dark`)}}function v(e){let t={..._(),...e};t.light=g(t.light,`light`),t.dark=g(t.dark,`dark`);try{localStorage.setItem(d,JSON.stringify(t)),m=null}catch{m=t}return window.dispatchEvent(new CustomEvent(f,{detail:t})),t}function y(e){h||(h=!0,window.addEventListener(`storage`,e=>{(e.key===d||e.key===null)&&window.dispatchEvent(new CustomEvent(f,{detail:_()}))}));let t=t=>e(t.detail);return window.addEventListener(f,t),()=>window.removeEventListener(f,t)}function b(){return u.flatMap(({id:e,mode:t,colors:n})=>n?[`:host([data-editor-theme="${e}"]) {
|
|
7
|
+
--cp-bg: ${n.bg};
|
|
8
|
+
--cp-fg: ${n.fg};
|
|
9
|
+
--cp-muted: ${n.muted};
|
|
10
|
+
--cp-border: ${n.border};
|
|
11
|
+
--cp-surface: ${n.surface};
|
|
12
|
+
--cp-accent: ${n.accent};
|
|
13
|
+
--cp-accent-fg: ${n.accentFg};
|
|
14
|
+
--cp-danger: ${n.danger};
|
|
15
|
+
--cp-ok: ${n.ok};
|
|
16
|
+
color-scheme: ${t};
|
|
17
|
+
}`]:[]).join(`
|
|
18
|
+
`)}async function x(e){try{return await E(e)}catch(t){return console.warn(`[code-playpad] CodeMirror unavailable, using plain textarea:`,t),D(e)}}var S=/* @__PURE__ */ new Map,C=/* @__PURE__ */ new Set,w=!1;function T(){w||(w=!0,queueMicrotask(()=>{w=!1;for(let e of C){let t=[...e.adoptedStyleSheets];e.adoptedStyleSheets=[],e.adoptedStyleSheets=t}}))}async function E(e){let[t,n,r,i,a,o,s]=await Promise.all([import(`./dist-D4P7t1AU.js`).then(e=>e.s),import(`./dist-CjnVq6q1.js`).then(e=>e.x),import(`./dist-g8djAEMH.js`),import(`./dist-CTLX4tws.js`),import(`./dist-_fde-E8H.js`).then(e=>e.n),import(`./dist-DHeVjdBc.js`),import(`./dist-IFh_mUXG.js`).then(e=>e.t)]),{EditorView:c,keymap:l,lineNumbers:d,highlightActiveLine:f,highlightActiveLineGutter:p,highlightSpecialChars:m,drawSelection:h,rectangularSelection:g,crosshairCursor:_}=t,{EditorState:v,Compartment:y}=n,{defaultKeymap:b,history:x,historyKeymap:w,indentWithTab:E}=r,{syntaxHighlighting:D,defaultHighlightStyle:O,HighlightStyle:k,indentOnInput:A,bracketMatching:j,foldGutter:M,foldKeymap:N}=i,{autocompletion:P,closeBrackets:F,closeBracketsKeymap:I,completionKeymap:L}=a,R=new y,z=new y,B=new y,V=S.get(`default-light`)??[c.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`}}),D(O,{fallback:!0})];S.set(`default-light`,V);let{tags:H}=s,U=(e,t)=>[c.theme({"&":{color:e.fg,backgroundColor:e.bg},".cm-content":{caretColor:e.fg},".cm-gutters":{backgroundColor:e.surface,color:e.muted,border:`none`},".cm-activeLine":{backgroundColor:e.activeLine},".cm-activeLineGutter":{backgroundColor:e.selection},".cm-cursor, .cm-dropCursor":{borderLeftColor:e.fg},"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection":{backgroundColor:e.selection},".cm-tooltip":{backgroundColor:e.surface,color:e.fg,border:`1px solid ${e.border}`},".cm-tooltip-autocomplete > ul > li[aria-selected]":{backgroundColor:e.selection,color:e.fg}},{dark:t}),D(k.define([{tag:[H.comment,H.meta],color:e.comment,fontStyle:`italic`},{tag:[H.keyword,H.operatorKeyword,H.modifier],color:e.keyword},{tag:[H.string,H.special(H.string),H.regexp],color:e.string},{tag:[H.number,H.bool,H.null,H.atom],color:e.number},{tag:[H.function(H.variableName),H.function(H.propertyName),H.definition(H.function(H.variableName))],color:e.fn},{tag:[H.typeName,H.className,H.namespace,H.tagName],color:e.type},{tag:[H.variableName,H.propertyName,H.attributeName],color:e.variable},{tag:H.invalid,color:e.keyword,textDecoration:`underline`}]))],W=(e,t)=>{let n=u.find(e=>e.id===t);if(!n?.colors)return e?o.oneDark:V;let r=S.get(n.id);return r||(r=U(n.colors,n.mode===`dark`),S.set(n.id,r)),r},G=l.of([{key:`Mod-Enter`,preventDefault:!0,run:()=>(e.onRun?.(),!0)},{key:`Shift-Enter`,preventDefault:!0,run:()=>(e.onRun?.(),!0)}]),K=e.dark,q=e.themeId,J=e.readOnly,Y=e.language??[],X=t=>v.create({doc:t,extensions:[d(),p(),m(),x(),M(),h(),v.allowMultipleSelections.of(!0),A(),j(),F(),P(),g(),_(),f(),G,l.of([...I,...b,...w,...N,...L,E]),c.lineWrapping,B.of(Y),R.of(W(K,q)),z.of(v.readOnly.of(J)),c.updateListener.of(t=>{t.startState.facet(c.styleModule)!==t.state.facet(c.styleModule)&&T(),t.docChanged&&e.onChange?.(t.state.doc.toString())})]}),Z=new c({parent:e.parent,state:X(e.doc)});C.add(Z.root),T();let Q=/* @__PURE__ */ new Map,$=e.name??``;return{fallback:!1,getCode:()=>Z.state.doc.toString(),setCode(e){Z.dispatch({changes:{from:0,to:Z.state.doc.length,insert:e}})},openFile(e,t){if(e===$)return;Q.set($,Z.state);let n=Q.get(e);Z.setState(n??X(t)),$=e,n&&Z.dispatch({effects:[R.reconfigure(W(K,q)),z.reconfigure(v.readOnly.of(J)),B.reconfigure(Y)]}),T()},fileCode(e,t){if(e===$)return Z.state.doc.toString();let n=Q.get(e);return n?n.doc.toString():t},forgetFiles(e){for(let t of[...Q.keys()])e.includes(t)||Q.delete(t)},setTheme(e,t){K=e,q=t,Z.dispatch({effects:R.reconfigure(W(K,q))})},setReadOnly(e){J=e,Z.dispatch({effects:z.reconfigure(v.readOnly.of(J))})},setLanguage(e){Y=e,Z.dispatch({effects:B.reconfigure(Y)})},focus:()=>Z.focus(),destroy(){C.delete(Z.root),Z.destroy()}}}function D(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=/* @__PURE__ */ 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 O=/* @__PURE__ */ new Map,k=/* @__PURE__ */ new Map;function A(e,t){O.set(e,t)}function j(){return[...O.keys()]}function M(e){let t=k.get(e);if(t)return t;let n=O.get(e);if(!n)return Promise.reject(/* @__PURE__ */ Error(`Unknown runtime "${e}". Registered: ${j().join(`, `)||`none`}`));let r=n().catch(t=>{throw k.delete(e),t});return k.set(e,r),r}A(`python`,()=>import(`./pyodide-QurAOd7j.js`).then(e=>e.pythonRuntime)),A(`javascript`,()=>import(`./javascript-BBiCDtZ3.js`).then(e=>e.javascriptRuntime)),A(`typescript`,()=>import(`./javascript-BBiCDtZ3.js`).then(e=>e.typescriptRuntime)),A(`java`,()=>import(`./java-DjuG1fCk.js`).then(e=>e.javaRuntime)),A(`c`,()=>import(`./cpp-Bhr_Zgfk.js`).then(e=>e.cRuntime)),A(`cpp`,()=>import(`./cpp-Bhr_Zgfk.js`).then(e=>e.cppRuntime)),A(`react`,()=>import(`./react-ALhWeEZ5.js`).then(e=>e.reactRuntime));var N=String.raw`
|
|
7
19
|
:host {
|
|
8
20
|
--cp-bg: #ffffff;
|
|
9
21
|
--cp-fg: #1f2328;
|
|
@@ -38,6 +50,8 @@ import{n as e,r as t,t as n}from"./hints-CCMgezw9.js";import{c as r,i,n as a,r a
|
|
|
38
50
|
color-scheme: dark;
|
|
39
51
|
}
|
|
40
52
|
|
|
53
|
+
${b()}
|
|
54
|
+
|
|
41
55
|
* { box-sizing: border-box; }
|
|
42
56
|
|
|
43
57
|
.cp-root {
|
|
@@ -54,6 +68,7 @@ import{n as e,r as t,t as n}from"./hints-CCMgezw9.js";import{c as r,i,n as a,r a
|
|
|
54
68
|
display: flex;
|
|
55
69
|
align-items: center;
|
|
56
70
|
gap: 8px;
|
|
71
|
+
flex-wrap: wrap;
|
|
57
72
|
padding: 6px 8px;
|
|
58
73
|
background: var(--cp-surface);
|
|
59
74
|
border-bottom: 1px solid var(--cp-border);
|
|
@@ -61,6 +76,53 @@ import{n as e,r as t,t as n}from"./hints-CCMgezw9.js";import{c as r,i,n as a,r a
|
|
|
61
76
|
|
|
62
77
|
.cp-spacer { flex: 1 1 auto; }
|
|
63
78
|
|
|
79
|
+
.cp-icon-button, .cp-theme-picker {
|
|
80
|
+
position: relative;
|
|
81
|
+
display: inline-flex;
|
|
82
|
+
align-items: center;
|
|
83
|
+
justify-content: center;
|
|
84
|
+
flex: none;
|
|
85
|
+
width: 28px;
|
|
86
|
+
height: 27px;
|
|
87
|
+
padding: 0;
|
|
88
|
+
border: 1px solid var(--cp-border);
|
|
89
|
+
border-radius: 6px;
|
|
90
|
+
background: var(--cp-bg);
|
|
91
|
+
color: var(--cp-fg);
|
|
92
|
+
cursor: pointer;
|
|
93
|
+
}
|
|
94
|
+
.cp-icon-button[hidden], .cp-theme-picker[hidden] { display: none; }
|
|
95
|
+
.cp-icon-button svg, .cp-theme-picker svg {
|
|
96
|
+
width: 15px;
|
|
97
|
+
height: 15px;
|
|
98
|
+
fill: none;
|
|
99
|
+
stroke: currentColor;
|
|
100
|
+
stroke-width: 2;
|
|
101
|
+
stroke-linecap: round;
|
|
102
|
+
stroke-linejoin: round;
|
|
103
|
+
}
|
|
104
|
+
.cp-theme-picker { overflow: hidden; }
|
|
105
|
+
.cp-theme-picker:hover { border-color: var(--cp-accent); }
|
|
106
|
+
.cp-theme-picker:focus-within { outline: 2px solid var(--cp-accent); outline-offset: 1px; }
|
|
107
|
+
/* The native list, laid invisibly over the icon: keyboard and phone pickers come free. */
|
|
108
|
+
.cp-theme-picker select {
|
|
109
|
+
position: absolute;
|
|
110
|
+
inset: 0;
|
|
111
|
+
width: 100%;
|
|
112
|
+
height: 100%;
|
|
113
|
+
opacity: 0;
|
|
114
|
+
min-width: 0;
|
|
115
|
+
margin: 0;
|
|
116
|
+
padding: 0;
|
|
117
|
+
border: 0;
|
|
118
|
+
appearance: none;
|
|
119
|
+
cursor: pointer;
|
|
120
|
+
font-size: 16px;
|
|
121
|
+
}
|
|
122
|
+
.cp-theme-sun { display: none; }
|
|
123
|
+
:host([data-resolved-theme="dark"]) .cp-theme-sun { display: block; }
|
|
124
|
+
:host([data-resolved-theme="dark"]) .cp-theme-moon { display: none; }
|
|
125
|
+
|
|
64
126
|
.cp-status {
|
|
65
127
|
font-size: 12px;
|
|
66
128
|
color: var(--cp-muted);
|
|
@@ -291,6 +353,187 @@ table.cp-table th { background: var(--cp-bg); }
|
|
|
291
353
|
}
|
|
292
354
|
.cp-progress[hidden] { display: none; }
|
|
293
355
|
|
|
356
|
+
/* language="react". The widget is the container: lesson columns are narrow even
|
|
357
|
+
on a large screen, so the viewport says nothing about the room there is. */
|
|
358
|
+
.cp-root.cp-has-preview { container-type: inline-size; }
|
|
359
|
+
.cp-preview-pane { display: none; }
|
|
360
|
+
.cp-has-preview .cp-preview-pane { display: flex; flex-direction: column; }
|
|
361
|
+
.cp-has-preview .cp-preview-pane .cp-output { flex: 1 1 auto; border-top: 0; min-height: 40px; }
|
|
362
|
+
.cp-preview {
|
|
363
|
+
position: relative;
|
|
364
|
+
flex: 0 0 var(--cp-preview-height, 320px);
|
|
365
|
+
height: var(--cp-preview-height, 320px);
|
|
366
|
+
border-top: 1px solid var(--cp-border);
|
|
367
|
+
background: var(--cp-surface);
|
|
368
|
+
overflow: hidden;
|
|
369
|
+
}
|
|
370
|
+
.cp-preview-frame {
|
|
371
|
+
display: block;
|
|
372
|
+
width: 100%;
|
|
373
|
+
height: 100%;
|
|
374
|
+
border: 0;
|
|
375
|
+
background: #ffffff;
|
|
376
|
+
}
|
|
377
|
+
.cp-preview-banner {
|
|
378
|
+
position: absolute;
|
|
379
|
+
left: 0;
|
|
380
|
+
right: 0;
|
|
381
|
+
bottom: 0;
|
|
382
|
+
max-height: 60%;
|
|
383
|
+
margin: 0;
|
|
384
|
+
padding: 10px 12px;
|
|
385
|
+
overflow: auto;
|
|
386
|
+
border-top: 3px solid var(--cp-danger);
|
|
387
|
+
background: var(--cp-bg);
|
|
388
|
+
color: var(--cp-danger);
|
|
389
|
+
font-family: var(--cp-font-mono);
|
|
390
|
+
font-size: 12.5px;
|
|
391
|
+
line-height: 1.5;
|
|
392
|
+
white-space: pre-wrap;
|
|
393
|
+
word-break: break-word;
|
|
394
|
+
}
|
|
395
|
+
.cp-preview-notice {
|
|
396
|
+
position: absolute;
|
|
397
|
+
top: 8px;
|
|
398
|
+
left: 8px;
|
|
399
|
+
right: 8px;
|
|
400
|
+
padding: 8px 10px;
|
|
401
|
+
border: 1px solid var(--cp-border);
|
|
402
|
+
border-left: 3px solid var(--cp-accent);
|
|
403
|
+
border-radius: 6px;
|
|
404
|
+
background: var(--cp-bg);
|
|
405
|
+
color: var(--cp-fg);
|
|
406
|
+
font-size: 13px;
|
|
407
|
+
white-space: pre-wrap;
|
|
408
|
+
}
|
|
409
|
+
.cp-preview-notice[hidden] { display: none; }
|
|
410
|
+
.cp-output .cp-warn { color: #9a6700; }
|
|
411
|
+
:host([data-resolved-theme="dark"]) .cp-output .cp-warn { color: #d29922; }
|
|
412
|
+
.cp-edited-note { font-size: 12px; color: var(--cp-muted); white-space: nowrap; }
|
|
413
|
+
.cp-edited-note[hidden] { display: none; }
|
|
414
|
+
.cp-tabs button.cp-edited::after { content: ' ●'; color: var(--cp-accent); }
|
|
415
|
+
.cp-tab-folder { opacity: 0.65; }
|
|
416
|
+
|
|
417
|
+
@container (max-width: 480px) {
|
|
418
|
+
.cp-tab-folder { display: none; }
|
|
419
|
+
}
|
|
420
|
+
/* The dividers between sections. */
|
|
421
|
+
.cp-split {
|
|
422
|
+
display: none;
|
|
423
|
+
flex: none;
|
|
424
|
+
background: var(--cp-surface);
|
|
425
|
+
border: solid var(--cp-border);
|
|
426
|
+
border-width: 0 1px;
|
|
427
|
+
touch-action: none;
|
|
428
|
+
cursor: col-resize;
|
|
429
|
+
}
|
|
430
|
+
.cp-split:hover, .cp-split:focus-visible { background: var(--cp-accent); outline: none; }
|
|
431
|
+
.cp-split-main, .cp-split-console {
|
|
432
|
+
width: auto;
|
|
433
|
+
height: 7px;
|
|
434
|
+
border-width: 1px 0;
|
|
435
|
+
cursor: row-resize;
|
|
436
|
+
}
|
|
437
|
+
.cp-has-preview .cp-split-main { display: block; }
|
|
438
|
+
.cp-has-preview .cp-split-console { display: block; }
|
|
439
|
+
.cp-split-console:has(+ .cp-output[hidden]) { display: none; }
|
|
440
|
+
.cp-dragging .cp-preview-frame { pointer-events: none; }
|
|
441
|
+
.cp-dragging { user-select: none; }
|
|
442
|
+
.cp-dragging-x { cursor: col-resize; }
|
|
443
|
+
.cp-dragging-y { cursor: row-resize; }
|
|
444
|
+
.cp-root.cp-editor-sized .cp-editor { height: var(--cp-editor-height) !important; flex: none !important; }
|
|
445
|
+
.cp-root.cp-editor-sized .cp-editor .cm-editor { height: 100% !important; max-height: none !important; }
|
|
446
|
+
|
|
447
|
+
/* Open in window. */
|
|
448
|
+
.cp-window-button { display: none; }
|
|
449
|
+
.cp-has-preview .cp-window-button { display: inline-flex; }
|
|
450
|
+
:host([data-window]) .cp-window-button { display: none; }
|
|
451
|
+
.cp-window-note { display: none; align-items: center; gap: 8px; padding: 14px 12px; color: var(--cp-muted); }
|
|
452
|
+
.cp-root.cp-popped .cp-window-note { display: flex; }
|
|
453
|
+
.cp-root.cp-popped .cp-toolbar, .cp-root.cp-popped .cp-body { display: none; }
|
|
454
|
+
:host([data-window]) { height: 100%; margin: 0; contain: strict; }
|
|
455
|
+
:host([data-window]) .cp-root {
|
|
456
|
+
display: flex;
|
|
457
|
+
flex-direction: column;
|
|
458
|
+
height: 100%;
|
|
459
|
+
border: 0;
|
|
460
|
+
border-radius: 0;
|
|
461
|
+
}
|
|
462
|
+
:host([data-window]) .cp-body { flex: 1 1 0; min-height: 0; }
|
|
463
|
+
:host([data-window]) .cp-source, :host([data-window]) .cp-preview-pane { min-height: 0; }
|
|
464
|
+
:host([data-window]) .cp-root:not(.cp-editor-sized) .cp-editor { flex: 1 1 0; height: auto; min-height: 0; }
|
|
465
|
+
:host([data-window]) .cp-editor .cm-editor { height: 100%; max-height: none; }
|
|
466
|
+
:host([data-window]) .cp-preview-pane .cp-output { max-height: none; }
|
|
467
|
+
:host([data-window]) .cp-body { display: flex; flex-direction: column; }
|
|
468
|
+
:host([data-window]) .cp-source { flex: 1 1 0; display: flex; flex-direction: column; }
|
|
469
|
+
:host([data-window]) .cp-has-tree .cp-source { display: grid; }
|
|
470
|
+
:host([data-window]) .cp-preview-pane { flex: 1 1 0; }
|
|
471
|
+
|
|
472
|
+
/* file-view="tree": the files in a column beside the editor. */
|
|
473
|
+
.cp-root.cp-has-tree { container-type: inline-size; }
|
|
474
|
+
.cp-has-tree .cp-source {
|
|
475
|
+
display: grid;
|
|
476
|
+
grid-template-columns: var(--cp-tree-width, 200px) 7px minmax(0, 1fr);
|
|
477
|
+
grid-template-rows: 1fr auto;
|
|
478
|
+
}
|
|
479
|
+
.cp-has-tree .cp-source > :not(.cp-tabs, .cp-split-tree) { grid-column: 3; }
|
|
480
|
+
.cp-has-tree .cp-split-tree { display: block; grid-column: 2; grid-row: 1 / span 2; }
|
|
481
|
+
.cp-tabs.cp-tree {
|
|
482
|
+
display: block;
|
|
483
|
+
grid-column: 1;
|
|
484
|
+
grid-row: 1 / span 2;
|
|
485
|
+
padding: 6px 0;
|
|
486
|
+
overflow: auto;
|
|
487
|
+
border-bottom: 0;
|
|
488
|
+
}
|
|
489
|
+
.cp-tabs.cp-tree[hidden] { display: none; }
|
|
490
|
+
.cp-tabs.cp-tree button {
|
|
491
|
+
display: block;
|
|
492
|
+
width: 100%;
|
|
493
|
+
padding: 5px 8px 5px calc(22px + var(--cp-depth, 0) * 12px);
|
|
494
|
+
border-bottom: 0;
|
|
495
|
+
border-left: 2px solid transparent;
|
|
496
|
+
text-align: left;
|
|
497
|
+
overflow: hidden;
|
|
498
|
+
text-overflow: ellipsis;
|
|
499
|
+
}
|
|
500
|
+
.cp-tabs.cp-tree button[aria-pressed='true'] { border-left-color: var(--cp-accent); }
|
|
501
|
+
.cp-tabs.cp-tree button.cp-entry::before {
|
|
502
|
+
content: '▸';
|
|
503
|
+
display: inline-block;
|
|
504
|
+
width: 12px;
|
|
505
|
+
margin: 0 0 0 -12px;
|
|
506
|
+
}
|
|
507
|
+
.cp-tabs.cp-tree .cp-tree-folder {
|
|
508
|
+
padding-left: calc(8px + var(--cp-depth, 0) * 12px);
|
|
509
|
+
color: var(--cp-fg);
|
|
510
|
+
}
|
|
511
|
+
.cp-tabs.cp-tree .cp-tree-folder::before {
|
|
512
|
+
content: '⌄';
|
|
513
|
+
display: inline-block;
|
|
514
|
+
width: 14px;
|
|
515
|
+
color: var(--cp-muted);
|
|
516
|
+
}
|
|
517
|
+
.cp-tabs.cp-tree .cp-tree-folder[aria-expanded='false']::before { content: '›'; }
|
|
518
|
+
@container (max-width: 420px) {
|
|
519
|
+
.cp-has-tree .cp-source { display: block; }
|
|
520
|
+
.cp-has-tree .cp-split-tree { display: none; }
|
|
521
|
+
.cp-tabs.cp-tree { max-height: 150px; border-bottom: 1px solid var(--cp-border); }
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/* Only a preview sits beside the code: a tree makes any widget a container. */
|
|
525
|
+
@container (min-width: 760px) {
|
|
526
|
+
.cp-has-preview .cp-body { display: flex; align-items: stretch; }
|
|
527
|
+
.cp-has-preview .cp-source { flex: 0 0 var(--cp-source-width, calc(50% - 4px)); min-width: 0; }
|
|
528
|
+
.cp-has-preview .cp-preview-pane { flex: 1 1 0; min-width: 0; }
|
|
529
|
+
.cp-has-preview .cp-preview { border-top: 0; }
|
|
530
|
+
.cp-has-preview .cp-source:not(:has(.cp-tree)) { display: flex; flex-direction: column; }
|
|
531
|
+
.cp-has-preview .cp-source:not(:has(.cp-tree)) .cp-editor { flex: 1 1 auto; }
|
|
532
|
+
.cp-split.cp-split-main { width: 7px; height: auto; cursor: col-resize; border-width: 0 1px; }
|
|
533
|
+
:host([data-window]) .cp-body { flex-direction: row; }
|
|
534
|
+
:host([data-window]) .cp-source { flex: 0 0 var(--cp-source-width, calc(50% - 4px)); }
|
|
535
|
+
}
|
|
536
|
+
|
|
294
537
|
@keyframes cp-slide {
|
|
295
538
|
0% { background-position: -40% 0; }
|
|
296
539
|
100% { background-position: 140% 0; }
|
|
@@ -299,31 +542,60 @@ table.cp-table th { background: var(--cp-bg); }
|
|
|
299
542
|
@media (prefers-reduced-motion: reduce) {
|
|
300
543
|
.cp-progress { animation: none; background-position: 0 0; background-size: 100% 100%; opacity: 0.4; }
|
|
301
544
|
}
|
|
302
|
-
`,
|
|
545
|
+
`,P=e=>()=>import(`./dist-BwlTZqCY.js`).then(t=>t.javascript(e)),F={py:()=>import(`./dist-CRXZcpYD.js`).then(e=>e.python()),pyi:()=>import(`./dist-CRXZcpYD.js`).then(e=>e.python()),js:P({}),mjs:P({}),cjs:P({}),jsx:P({jsx:!0}),ts:P({typescript:!0}),mts:P({typescript:!0}),cts:P({typescript:!0}),tsx:P({typescript:!0,jsx:!0}),json:()=>import(`./dist-BDifu2bQ.js`).then(e=>e.json()),css:()=>import(`./dist-UbI3_a5S.js`).then(e=>e.css()),html:()=>import(`./dist-C41hAfPr.js`).then(e=>e.html()),c:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),h:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),cpp:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),cc:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),cxx:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),hpp:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),hxx:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),java:()=>import(`./dist-ixcYRC9x.js`).then(e=>e.java())};async function I(e,t){let n=e.includes(`.`)?e.slice(e.lastIndexOf(`.`)+1).toLowerCase():``,r=t===`react`&&n===`js`?F.jsx:F[n];return r?r().catch(()=>null):null}var L=`code-playpad`,R=1,z=`snippets`,B=`progress`,V=null;function H(){return typeof indexedDB>`u`?Promise.reject(/* @__PURE__ */ Error(`IndexedDB unavailable`)):(V||=new Promise((e,t)=>{let n=indexedDB.open(L,R);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(z)||e.createObjectStore(z),e.objectStoreNames.contains(B)||e.createObjectStore(B,{keyPath:`id`})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}).catch(e=>{throw V=null,e}),V)}function U(e,t,n){return H().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 W(e,t){return U(z,`readwrite`,n=>n.put(t,e)).then(()=>void 0)}function G(e){return U(z,`readonly`,t=>t.get(e)).then(e=>e??null)}function K(e){return U(z,`readwrite`,t=>t.delete(e)).then(()=>void 0)}function q(e,t={}){let n={completed:!0,...t,id:e,updatedAt:Date.now()};return U(B,`readwrite`,e=>e.put(n)).then(()=>n)}function J(e){return U(B,`readonly`,t=>t.get(e)).then(e=>e??null)}function Y(){return U(B,`readonly`,e=>e.getAll())}var X=`code-playpad`;function Z(e){let t=e.replace(/\t/g,` `).split(`
|
|
303
546
|
`);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(`
|
|
304
|
-
`)}var
|
|
305
|
-
`,`cp-err`),this.#oe(`py-run`,{code:a,entry:i,files:
|
|
547
|
+
`)}var Q=2e5,$=`playpad-file`,ee={python:`main.py`,javascript:`main.js`,typescript:`main.ts`,java:`Main.java`,c:`main.c`,cpp:`main.cpp`,react:`src/main.jsx`};function te(e){return ee[e]??`main.txt`}var ne=e=>e.tagName===`SCRIPT`&&e.getAttribute(`type`)===`text/plain`;function re(e){return[...e.children].filter(e=>e.tagName.toLowerCase()===$&&[...e.children].some(e=>!ne(e))).map(e=>e.getAttribute(`name`)??``)}function ie(e,t){let n={};for(let t of e.children){if(t.tagName.toLowerCase()!==$)continue;let e=t.getAttribute(`name`),r=[...t.children].find(ne);e&&(n[e]=Z((r??t).textContent??``))}if(Object.keys(n).length)return n;let r=[...e.childNodes].filter(e=>e.nodeType!==Node.ELEMENT_NODE||e.tagName.toLowerCase()!==$),i=r.some(e=>e.nodeType===Node.ELEMENT_NODE),a=Z(r.filter(e=>!(i&&e.nodeType===Node.TEXT_NODE&&!(e.textContent??``).trim())).map(e=>e.textContent??``).join(``));return{[t]:a}}function ae(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 oe=typeof HTMLElement>`u`?class{}:HTMLElement,se=class extends oe{static get observedAttributes(){return[`language`,`height`,`min-height`,`max-height`,`preview-height`,`file-view`,`open-file`,`theme`,`theme-controls`,`readonly`,`autorun`,`stdin`,`persist`,`entry`,`practice`]}#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=null;#x=!1;#S=!1;#C=null;#w=null;#T=null;#E=()=>this.#fe();#D=null;#O=null;#k=!0;#A=[];#j=null;#M=null;#N=null;#P=0;#F=!1;#I=null;#L;#R;#z=null;#B=[];#V=/* @__PURE__ */ new Set;#H=null;#U=null;#W=null;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.#Z()}get practice(){if(this.#I)return this.#I;let e=this.getAttribute(`practice`);if(!e)return null;try{return JSON.parse(e)}catch{return null}}set practice(e){this.#I=e}get files(){return this.#re()}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},this.#B=[],t.includes(this.#g)||(this.#g=this.#te()),this.#u?.forgetFiles([]),this.#Z(),this.#ie(),this.#X()}get entry(){return this.#te()}set entry(e){this.setAttribute(`entry`,e)}openFile(e){if(e in this.#m){this.#u&&(this.#m[this.#g]=this.#u.getCode(),this.#u.openFile(e,this.#m[e]??``)),this.#g=e;for(let t=e.indexOf(`/`);t!==-1;t=e.indexOf(`/`,t+1))this.#V.delete(e.slice(0,t));this.#ie(),this.#X()}}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.#re()}reset(){this.#m={...this.#h},this.#g=this.#te(),this.#u?.forgetFiles([]),this.#Z(),this.#ie(),this.#he(),this.#s.hidden=!0,this.#se(),this.#z=null,this.#ce(),this.#me(this.#f?.ready?`${this.#f.label} ready`:``,`idle`)}async run(){if(this.#H)return this.#H.widget.run();if(this.#y)return;await this.#d;let e=this.#re(),r=this.getAttribute(`entry`);if(r&&!(r in e))return this.#$(r,e);this.#Q=!1;let i=this.#te(),a=e[i]??``;this.#y=!0,this.#x=!1,this.#n.disabled=!0,this.#r.hidden=!1,this.#he(),this.#s.hidden=!1;let o=this.practice;this.hasAttribute(`practice`)&&!o&&this.#ge(`The practice attribute is not valid JSON.
|
|
548
|
+
`,`cp-err`),this.#oe()&&(this.#z=e,this.#ce(),this.#B.length&&this.#ge(`${this.#B.join(`, `)}: HTML tags in this file's markup were read as elements, so its code is incomplete. Write < as <, or put the code in <script type="text/plain">. A <script> left unescaped runs on the host page.\n`,`cp-err`)),this.#Se(`py-run`,{code:a,entry:i,files:e,language:this.language,...o?{practice:o}:{}});try{let r=await this.#Y();if(this.#x)throw new t;if(o&&!r.supportsPractice)throw Error(`Practice mode is not available for ${r.label}.`);this.#me(`Queued…`,`busy`),this.#o.hidden=!1;let s=r.run(a,{stdin:this.#l.value,files:e,entry:i,onStart:()=>this.#me(`Running…`,`busy`),onProgress:e=>this.#me(e.message,`busy`),onStdout:e=>this.#ge(e),onStderr:e=>this.#ge(e,`cp-err`),onEcho:e=>this.#ge(e,`cp-in`),onStdinRequest:()=>this.#ve(),...o?{practice:o}:{},...this.#oe()?{preview:{host:this.#L,onStart:()=>this.#me(`Running…`,`busy`),onConsole:(e,t)=>{this.#ge(`${t}\n`,e===`error`?`cp-err`:e===`warn`?`cp-warn`:void 0),this.#Ce(`playpad-console`,{level:e,text:t,language:this.language})},onRender:e=>this.#Ce(`playpad-render`,{rootText:e,language:this.language}),onError:e=>{this.#me(`Error`,`error`),this.#Se(`py-error`,{...e,language:this.language})}}}:{}});this.#b={runtime:r,run:s};let c=await s;if(c.table&&this.#xe(c.table),c.value!==void 0&&this.#ge(`${c.value}\n`,`cp-value`),c.hint&&this.#be(c.hint,n.has(c)),c.failed=r.statusDecidesFailure?c.failed===!0:!!c.stderr,c.failed)this.#me(`Error · ${c.durationMs} ms`,`error`),this.#Se(`py-error`,{message:c.problem?.message??c.stderr??``,hint:c.hint,language:this.language,...c.problem??{}});else if(c.cases){let e=c.cases.filter(e=>e.expected!==void 0).length,t=c.passed===e;this.#me(e?`${c.passed} of ${e} passed · ${c.durationMs} ms`:`Done in ${c.durationMs} ms`,t?`ok`:`error`)}else this.#me(`Done in ${c.durationMs} ms`,`ok`);return this.#Se(`py-output`,{...c,language:this.language}),c}catch(e){if(e instanceof t)this.#ge(`
|
|
306
549
|
[stopped]
|
|
307
|
-
`,`cp-err`),this.#
|
|
308
|
-
`,`cp-err`),this.#
|
|
550
|
+
`,`cp-err`),this.#me(`Stopped`,`error`);else{let t=e instanceof Error?e.message:String(e);this.#ge(t+`
|
|
551
|
+
`,`cp-err`),this.#me(`Failed to start`,`error`),this.#Se(`py-error`,{message:t,language:this.language})}return}finally{this.#b=null,this.#ye(null),this.#_e(),this.#y=!1,this.#n.disabled=!1,this.#r.hidden=!(this.#oe()&&this.#f?.hasLivePreview?.(this.#L)),this.#o.hidden=!0}}stop(){this.#H?this.#H.widget.stop():this.#b?this.#b.runtime.stop?.(this.#b.run):this.#y?this.#x=!0:this.#oe()&&this.#f?.hasLivePreview?.(this.#L)&&(this.#se(),this.#r.hidden=!0,this.#me(`Stopped`,`idle`))}openWindow(){if(this.#H)return this.#H.window.focus(),!0;if(this.#U)return!1;let e=window.open(``,`_blank`,`popup,width=1280,height=800`);if(!e)return this.#me(`The browser blocked the new window`,`error`),!1;let t=this.#re(),n=this.#g,r=document.createElement(this.localName);for(let e of[`language`,`entry`,`file-view`,`preview-height`,`theme`,`theme-controls`,`readonly`,`stdin`]){let t=this.getAttribute(e);t!==null&&r.setAttribute(e,t)}r.setAttribute(`data-window`,``),r.#U=this,r.#W={...this.#h},r.#_=t,this.#se(),this.#r.hidden=!0,e.document.title=`Code playground`,e.document.documentElement.style.height=`100%`,e.document.body.style.cssText=`margin:0;height:100%`,e.document.body.append(r);let i=()=>this.closeWindow();return window.addEventListener(`pagehide`,i),this.#H={window:e,widget:r,onLeave:i,timer:setInterval(()=>{e.closed&&this.closeWindow()},300)},this.#e.querySelector(`.cp-root`)?.classList.add(`cp-popped`),r.#d?.then(()=>(r.openFile(n),r.run())),!0}closeWindow(){let e=this.#H;if(!e)return;this.#H=null,clearInterval(e.timer),window.removeEventListener(`pagehide`,e.onLeave);let{widget:t}=e,n=t.#re(),r=t.#g;t.#se(),t.remove(),e.window.closed||e.window.close(),this.#e.querySelector(`.cp-root`)?.classList.remove(`cp-popped`),this.files=n,this.openFile(r),this.#me(``,`idle`)}prewarm(){return this.#Y()}connectedCallback(){this.#F?(this.#fe(),this.#J()):!this.textContent?.trim()&&document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,()=>this.isConnected&&this.#G(),{once:!0}):this.#G()}disconnectedCallback(){this.#C?.disconnect(),this.#C=null,this.#w?.removeEventListener(`change`,this.#E),this.#w=null,this.#T?.disconnect(),this.#T=null,this.#D?.(),this.#D=null,this.#O&&clearTimeout(this.#O),this.#ye(null),setTimeout(()=>{this.isConnected||(this.closeWindow(),this.#se(),this.#u&&(this.#_=this.#re(),this.#u.destroy(),this.#u=null,this.#d=null,this.#F=!1))},0)}attributeChangedCallback(e,t,n){if(this.#F)switch(e){case`theme`:case`theme-controls`:this.#fe();break;case`height`:case`min-height`:case`max-height`:case`preview-height`:this.#pe();break;case`readonly`:this.#u?.setReadOnly(n!==null);break;case`stdin`:this.#c.hidden=n===null&&!this.#l.value;break;case`entry`:case`file-view`:this.#ie();break;case`language`:this.#se(),this.#e.querySelector(`.cp-root`)?.classList.toggle(`cp-has-preview`,this.#oe()),this.#f=null,this.#p=null,this.#S=!1,this.#Y().catch(()=>{})}}#G(){this.#F=!0,this.#h=this.#W??ie(this,this.#ee()),this.#B=this.#oe()?re(this):[],this.#m=this.#_??{...this.#h},this.#g=this.#ne(),this.#K(),this.#fe(),this.#pe();let e=this.getAttribute(`persist`);this.#d=(async()=>{if(e&&this.#_==null){let t=await G(e).catch(()=>null),n=t==null?null:ae(t,this.#ee());if(n){let e={},t=Object.keys(this.#h),r=Object.keys(n);for(let r of t)e[r]=n[r]??this.#h[r];t.length===1&&r.length===1&&!(t[0]in n)&&(e[t[0]]=n[r[0]]),this.#m=e,this.#g=this.#ne()}}this.#ie();let t=await M(this.language).catch(()=>null),n=t?await t.editorLanguage().catch(()=>null):null;this.#u=await x({parent:this.#t,doc:this.#m[this.#g]??``,name:this.#g,dark:this.#ue(),themeId:this.#de(),readOnly:this.hasAttribute(`readonly`),language:n,onRun:()=>void this.run(),onChange:e=>this.#le(e)}),this.#_=null,this.#fe(),this.#X()})(),this.#J()}#K(){let e=document.createElement(`style`);e.textContent=N;let t=document.createElement(`div`);t.className=this.#oe()?`cp-root cp-has-preview`:`cp-root`,t.innerHTML=`
|
|
309
552
|
<div class="cp-toolbar">
|
|
310
553
|
<button class="cp-primary" part="run-button" data-action="run">Run</button>
|
|
311
554
|
<button class="cp-danger" part="stop-button" data-action="stop" hidden>Stop</button>
|
|
312
555
|
<button data-action="reset">Reset</button>
|
|
313
556
|
<span class="cp-spacer"></span>
|
|
557
|
+
<button part="theme-button" class="cp-icon-button" data-action="theme">
|
|
558
|
+
<svg class="cp-theme-moon" viewBox="0 0 24 24" aria-hidden="true"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>
|
|
559
|
+
<svg class="cp-theme-sun" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>
|
|
560
|
+
</button>
|
|
561
|
+
<label part="editor-theme-picker" class="cp-theme-picker" title="Editor theme">
|
|
562
|
+
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 3a9 9 0 0 0 0 18c1.4 0 2-.9 2-1.8 0-1.2-1-1.7-1-2.7 0-1 .8-1.5 1.8-1.5H17a4 4 0 0 0 4-4c0-4.4-4-8-9-8z"/><circle cx="7.5" cy="11.5" r="1"/><circle cx="10.5" cy="7.5" r="1"/><circle cx="15.5" cy="7.5" r="1"/></svg>
|
|
563
|
+
<select aria-label="Editor theme">
|
|
564
|
+
${[`dark`,`light`].map(e=>`<optgroup label="${e===`dark`?`Dark`:`Light`}">${u.filter(t=>t.mode===e).map(e=>`<option value="${e.id}">${e.label}</option>`).join(``)}</optgroup>`).join(``)}
|
|
565
|
+
</select>
|
|
566
|
+
</label>
|
|
567
|
+
<button part="window-button" class="cp-icon-button cp-window-button" data-action="window" aria-label="Open in window" title="Open in a separate window you can resize">
|
|
568
|
+
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M14 4h6v6M20 4l-9 9M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/></svg>
|
|
569
|
+
</button>
|
|
570
|
+
<span class="cp-edited-note" hidden>Edited since the last run</span>
|
|
314
571
|
<span class="cp-status" data-state="idle"></span>
|
|
315
572
|
</div>
|
|
316
573
|
<div class="cp-progress" hidden></div>
|
|
317
|
-
<div class="cp-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
<
|
|
321
|
-
<textarea rows="2" spellcheck="false"></textarea>
|
|
574
|
+
<div class="cp-window-note">
|
|
575
|
+
<span>Running in a separate window.</span>
|
|
576
|
+
<button data-action="show-window">Show window</button>
|
|
577
|
+
<button data-action="close-window">Bring back here</button>
|
|
322
578
|
</div>
|
|
323
|
-
<
|
|
324
|
-
|
|
325
|
-
|
|
579
|
+
<div class="cp-body">
|
|
580
|
+
<div class="cp-source">
|
|
581
|
+
<div class="cp-tabs" part="tabs" hidden></div>
|
|
582
|
+
<div class="cp-split cp-split-tree" role="separator" tabindex="0" aria-orientation="vertical" aria-label="Resize the file tree"></div>
|
|
583
|
+
<div class="cp-editor"></div>
|
|
584
|
+
<div class="cp-stdin" hidden>
|
|
585
|
+
<label>Standard input — one value per line</label>
|
|
586
|
+
<textarea rows="2" spellcheck="false"></textarea>
|
|
587
|
+
</div>
|
|
588
|
+
</div>
|
|
589
|
+
<div class="cp-split cp-split-main" role="separator" tabindex="0" aria-label="Resize the code and the preview"></div>
|
|
590
|
+
<div class="cp-preview-pane">
|
|
591
|
+
<div class="cp-preview" part="preview"></div>
|
|
592
|
+
<div class="cp-split cp-split-console" role="separator" tabindex="0" aria-orientation="horizontal" aria-label="Resize the preview and the console"></div>
|
|
593
|
+
<pre class="cp-output" part="output" hidden></pre>
|
|
594
|
+
</div>
|
|
595
|
+
</div>`,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.#L=t.querySelector(`.cp-preview`),this.#R=t.querySelector(`.cp-edited-note`),this.#oe()||t.querySelector(`.cp-source`).after(this.#s),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,n=t.closest(`button[data-file]`);n&&this.openFile(n.getAttribute(`data-file`));let r=t.closest(`button[data-folder]`)?.dataset.folder;r!==void 0&&(this.#V.delete(r)||this.#V.add(r),this.#ie())}),this.#n.addEventListener(`click`,()=>void this.run()),this.#r.addEventListener(`click`,()=>this.stop()),this.#i.addEventListener(`click`,()=>this.reset()),t.querySelector(`[data-action="theme"]`).addEventListener(`click`,()=>{v({mode:this.#ue()?`light`:`dark`})}),t.querySelector(`.cp-theme-picker select`).addEventListener(`change`,e=>{let t=e.target.value,n=u.find(e=>e.id===t)?.mode;n&&v({mode:n,[n]:t})}),t.querySelector(`[data-action="window"]`).addEventListener(`click`,()=>this.openWindow()),t.querySelector(`[data-action="show-window"]`).addEventListener(`click`,()=>this.openWindow()),t.querySelector(`[data-action="close-window"]`).addEventListener(`click`,()=>this.closeWindow()),this.#q(t);let n=()=>void this.#Y().catch(()=>{});this.#t.addEventListener(`pointerdown`,n,{once:!0}),this.#t.addEventListener(`focusin`,n,{once:!0})}#q(e){let t=e.querySelector(`.cp-body`),n=e.querySelector(`.cp-source`),r=e.querySelector(`.cp-preview`),i=e.querySelector(`.cp-preview-pane`),a=this.#v,o=(e,t,n)=>Math.round(Math.max(t,Math.min(e,Math.max(t,n)))),s=(t,n)=>e.style.setProperty(t,`${n}px`),c=(t,n,r,i,a)=>{let o=()=>t.setAttribute(`aria-orientation`,n()===`x`?`vertical`:`horizontal`);t.addEventListener(`pointerdown`,a=>{a.preventDefault();let o=n()===`x`,s=o?a.clientX:a.clientY,c=r();t.setPointerCapture(a.pointerId),e.classList.add(`cp-dragging`,o?`cp-dragging-x`:`cp-dragging-y`);let l=e=>i(c+(o?e.clientX:e.clientY)-s),u=()=>{e.classList.remove(`cp-dragging`,`cp-dragging-x`,`cp-dragging-y`),t.removeEventListener(`pointermove`,l),t.removeEventListener(`pointerup`,u),t.removeEventListener(`pointercancel`,u)};t.addEventListener(`pointermove`,l),t.addEventListener(`pointerup`,u),t.addEventListener(`pointercancel`,u)}),t.addEventListener(`keydown`,e=>{let t={ArrowLeft:-24,ArrowUp:-24,ArrowRight:24,ArrowDown:24}[e.key];t&&(e.preventDefault(),i(r()+t))}),t.addEventListener(`dblclick`,a),t.addEventListener(`focus`,o),t.addEventListener(`pointerenter`,o)},l=()=>getComputedStyle(t).flexDirection===`row`&&getComputedStyle(t).display===`flex`;c(e.querySelector(`.cp-split-tree`),()=>`x`,()=>a.getBoundingClientRect().width,e=>s(`--cp-tree-width`,o(e,90,n.getBoundingClientRect().width-160)),()=>e.style.removeProperty(`--cp-tree-width`)),c(e.querySelector(`.cp-split-main`),()=>l()?`x`:`y`,()=>l()?n.getBoundingClientRect().width:this.#t.getBoundingClientRect().height,n=>{l()?s(`--cp-source-width`,o(n,200,t.getBoundingClientRect().width-200)):(s(`--cp-editor-height`,o(n,80,2e3)),e.classList.add(`cp-editor-sized`))},()=>{e.style.removeProperty(`--cp-source-width`),e.style.removeProperty(`--cp-editor-height`),e.classList.remove(`cp-editor-sized`)}),c(e.querySelector(`.cp-split-console`),()=>`y`,()=>r.getBoundingClientRect().height,e=>s(`--cp-preview-height`,o(e,60,l()||this.#U?i.getBoundingClientRect().height-40:2e3)),()=>e.style.removeProperty(`--cp-preview-height`))}#J(){this.#U||this.#C||typeof IntersectionObserver>`u`||(this.#C=new IntersectionObserver(e=>{e.some(e=>e.isIntersecting)&&(this.#C?.disconnect(),this.#C=null,this.#Y().then(()=>{this.hasAttribute(`autorun`)&&this.run()}).catch(()=>{}))},{rootMargin:`300px`}),this.#C.observe(this))}#Y(){return this.#p||=(async()=>{let e=await M(this.language);this.#f=e,!e.ready&&!this.#Q&&(this.#o.hidden=!1,this.#me(`Loading ${e.label}…`,`busy`));try{await e.load(e=>{!this.#y&&!this.#Q&&this.#me(e.message,e.phase===`ready`?`ok`:`busy`)})}catch(e){this.#p=null,this.#me(`Runtime unavailable`,`error`);let t=e instanceof Error?e.message:String(e);throw this.#ge(t+`
|
|
596
|
+
`,`cp-err`),this.#s.hidden=!1,e}finally{this.#o.hidden=!0}return this.#X(),this.#S||(this.#S=!0,this.#Q||this.#me(`${e.label} ready`,`ok`),this.#Se(`py-ready`,{language:e.id,label:e.label})),e})(),this.#p}async#X(){if(!this.#u)return;let e=this.#g,t=await I(e,this.language);if(t){this.#g===e&&this.#u?.setLanguage(t);return}let n=e.includes(`.`)?null:await(this.#f??await M(this.language).catch(()=>null))?.editorLanguage().catch(()=>null);this.#g===e&&this.#u?.setLanguage(n??[])}#Z(){this.#u?this.#u.setCode(this.#m[this.#g]??``):this.#d?.then(()=>{this.#u?.setCode(this.#m[this.#g]??``),this.#ie()})}#Q=!1;#$(e,t){let n=Object.keys(t),r=`This widget's entry is "${e}", but it has no file of that name${n.length?` (its files: ${n.join(`, `)})`:``}. Set entry to one of its files.\n`;this.#he(),this.#s.hidden=!1,this.#ge(r,`cp-err`),this.#Q=!0,this.#me(`Error · entry not found`,`error`);let i={stdout:``,stderr:r,durationMs:0,failed:!0};return this.#Se(`py-error`,{message:r,language:this.language}),this.#Se(`py-output`,{...i,language:this.language}),i}#ee(){return this.getAttribute(`entry`)||te(this.language)}#te(){let e=Object.keys(this.#m),t=this.getAttribute(`entry`);if(t&&e.includes(t))return t;let n=this.#oe()&&e.includes(`index.html`)?`index.html`:te(this.language);return e.includes(n)?n:e[0]??n}#ne(){let e=this.getAttribute(`open-file`);return e&&e in this.#m?e:this.#te()}#re(){if(this.#H)return this.#H.widget.#re();let e={...this.#m};if(this.#u)for(let t of Object.keys(e))e[t]=this.#u.fileCode(t,e[t]);return e}#ie(){let e=Object.keys(this.#m);this.#v.hidden=e.length<2;let t=!this.#v.hidden&&this.getAttribute(`file-view`)===`tree`;if(this.#v.classList.toggle(`cp-tree`,t),this.#e.querySelector(`.cp-root`)?.classList.toggle(`cp-has-tree`,t),this.#v.hidden){this.#v.replaceChildren();return}if(t){this.#ae(e),this.#ce();return}let n=this.#te();this.#v.replaceChildren(...e.map(e=>{let t=document.createElement(`button`);t.dataset.file=e;let r=e.lastIndexOf(`/`)+1;if(r){let n=document.createElement(`span`);n.className=`cp-tab-folder`,n.textContent=e.slice(0,r),t.setAttribute(`aria-label`,e),t.append(n)}return t.append(e.slice(r)),t.setAttribute(`aria-pressed`,String(e===this.#g)),e===n&&(t.classList.add(`cp-entry`),t.title=`entry point — this is the file Run executes`),t})),this.#ce()}#ae(e){let t=this.#te(),n=[],r=(i,a)=>{let o=e.filter(e=>e.startsWith(i)).map(e=>e.slice(i.length)),s=[...new Set(o.filter(e=>e.includes(`/`)).map(e=>e.slice(0,e.indexOf(`/`))))].sort();for(let e of s){let t=i+e,o=!this.#V.has(t),s=document.createElement(`button`);s.className=`cp-tree-folder`,s.dataset.folder=t,s.textContent=e,s.setAttribute(`aria-expanded`,String(o)),s.style.setProperty(`--cp-depth`,String(a)),n.push(s),o&&r(`${t}/`,a+1)}for(let e of o.filter(e=>!e.includes(`/`)).sort()){let r=i+e,o=document.createElement(`button`);o.dataset.file=r,o.textContent=e,o.setAttribute(`aria-label`,r),o.setAttribute(`aria-pressed`,String(r===this.#g)),o.style.setProperty(`--cp-depth`,String(a)),r===t&&(o.classList.add(`cp-entry`),o.title=`entry point — this is the file Run executes`),n.push(o)}};r(``,0),this.#v.replaceChildren(...n)}#oe(){return this.language===`react`}#se(){this.#L&&(this.#f?.dispose?.(this.#L),this.#L.replaceChildren())}#ce(){if(!this.#oe())return;let e=this.#re();for(let t of this.#v.querySelectorAll(`button[data-file]`)){let n=t.dataset.file;t.classList.toggle(`cp-edited`,e[n]!==this.#h[n])}let t=this.#z;this.#R.hidden=!t||Object.keys(e).every(n=>e[n]===t[n])}#le(e){this.#m[this.#g]=e,this.#ce();let t=this.getAttribute(`persist`);if(!t)return;this.#O&&clearTimeout(this.#O);let n=JSON.stringify(this.#re());this.#O=setTimeout(()=>void W(t,n).catch(()=>{}),400)}#ue(){let e=this.getAttribute(`theme`)??`auto`;if(e===`dark`)return!0;if(e===`light`)return!1;let t=_().mode;if(t)return t===`dark`;let n=typeof document>`u`?``:getComputedStyle(document.documentElement).colorScheme,r=n.includes(`dark`);return r===n.includes(`light`)?!!this.#w?.matches:r}#de(){return _()[this.#ue()?`dark`:`light`]}#fe(){this.#D??=y(this.#E),!this.#w&&typeof matchMedia==`function`&&(this.#w=matchMedia(`(prefers-color-scheme: dark)`),this.#w.addEventListener(`change`,this.#E)),!this.#T&&typeof MutationObserver==`function`&&typeof document<`u`&&(this.#T=new MutationObserver(this.#E),this.#T.observe(document.documentElement,{attributes:!0,attributeFilter:[`class`,`style`,`data-theme`,`data-color-scheme`,`color-scheme`]}));let e=this.#ue(),t=this.#de();this.setAttribute(`data-resolved-theme`,e?`dark`:`light`),this.setAttribute(`data-editor-theme`,t),this.#u?.setTheme(e,t);let n=this.getAttribute(`theme`),r=n===`light`||n===`dark`||this.getAttribute(`theme-controls`)===`off`,i=this.#e.querySelector(`[data-action="theme"]`),a=this.#e.querySelector(`.cp-theme-picker`);if(i&&a){let n=e?`Switch to the light theme`:`Switch to the dark theme`;i.hidden=a.hidden=r,i.title=n,i.setAttribute(`aria-label`,n),a.querySelector(`select`).value=t}}#pe(){for(let[e,t]of[[`height`,`--cp-height`],[`min-height`,`--cp-min-height`],[`max-height`,`--cp-max-height`],[`preview-height`,`--cp-preview-height`]]){let n=this.getAttribute(e);n===null||n===``?this.style.removeProperty(t):this.style.setProperty(t,/^\d+$/.test(n)?`${n}px`:n)}}#me(e,t){this.#a.textContent=e,this.#a.dataset.state=t}#he(){this.#N&&clearTimeout(this.#N),this.#N=null,this.#A=[],this.#P=0,this.#s.replaceChildren(),this.#k=!0}#ge(e,t){if(!e)return;let n=t===`cp-err`&&!this.#k?`\n${e}`:e;this.#k=n.endsWith(`
|
|
597
|
+
`),this.#A.push({text:n,className:t}),this.#N??=setTimeout(()=>this.#_e(),16)}#_e(){if(this.#N&&clearTimeout(this.#N),this.#N=null,!this.#A.length)return;let e=this.#A;this.#A=[];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.#P>=Q)break;let e=t.text;this.#P+e.length>Q&&(e=e.slice(0,Q-this.#P)+`
|
|
326
598
|
… output truncated for display — the full text is in the playpad-output event
|
|
327
|
-
`),this.#
|
|
328
|
-
`,`cp-in`):this.#
|
|
329
|
-
`,`cp-in`),this.#
|
|
599
|
+
`),this.#P+=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}#ve(){return this.#_e(),this.#ye(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.#j===e&&(this.#j=null,this.#M=null,t.remove(),n===null?this.#ge(`
|
|
600
|
+
`,`cp-in`):this.#ge(n+`
|
|
601
|
+
`,`cp-in`),this.#_e(),e(n))};t.addEventListener(`submit`,e=>{e.preventDefault(),a(n.value)}),i.addEventListener(`click`,()=>a(null)),n.addEventListener(`keydown`,e=>{(e.key===`Escape`||e.key===`d`&&e.ctrlKey)&&(e.preventDefault(),a(null))}),t.append(n,r,i),this.#s.hidden=!1,this.#s.appendChild(t),this.#s.scrollTop=this.#s.scrollHeight,this.#j=e,this.#M=a,n.focus({preventScroll:!0})})}#ye(e){this.#M?.(e),this.#M=null,this.#j=null}#be(e,t){this.#_e();let n=document.createElement(`div`);n.className=`cp-hint`,n.textContent=e,this.#s.hidden=!1,this.#s.appendChild(n),this.#s.scrollTop=this.#s.scrollHeight,t&&(this.#c.hidden=!1,this.#c.classList.add(`cp-attention`))}#xe(e){this.#_e();let t=document.createElement(`table`);t.className=`cp-table`;let n=t.createTHead().insertRow();for(let t of e.columns){let e=document.createElement(`th`);e.textContent=t,n.appendChild(e)}let r=t.createTBody();for(let t of e.rows){let e=r.insertRow();for(let n of t)e.insertCell().textContent=n==null?``:String(n)}this.#s.hidden=!1,this.#s.appendChild(t)}#Se(e,t){this.#Ce(e,t),this.#Ce(`playpad-${e.slice(3)}`,t)}#Ce(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0})),this.#U?.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}};function ce(e=X){typeof window<`u`&&typeof customElements<`u`&&(customElements.get(e)||customElements.define(e,se))}ce();export{se as CodePlayPadElement,u as EDITOR_THEMES,c as PYODIDE_VERSION,r as REACT_VERSION,t as RunStopped,e as WorkerUnavailable,Y as allProgress,K as clearSnippet,o as configureCpp,s as configurePython,a as configureReact,i as configureTypeScript,x as createEditor,ce as defineCodePlayPad,J as getProgress,M as getRuntime,_ as getThemePreference,j as listRuntimes,G as loadSnippet,y as onThemePreferenceChange,l as pyodideAssetUrls,A as registerRuntime,W as saveSnippet,q as setProgress,v as setThemePreference};
|