yourjs-box 1.7.0 → 1.8.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 CHANGED
@@ -7,6 +7,8 @@ Worker or the page itself. TypeScript works too.
7
7
  **[Live demo](https://westc.github.io/yourjs-box/)** ·
8
8
  [Examples](https://westc.github.io/yourjs-box/examples/)
9
9
 
10
+ ![JS Box running code one block at a time, expanding an object, showing a table and an error](demo.gif)
11
+
10
12
  ## Usage
11
13
 
12
14
  Add the script wherever you want the console to appear and put the code that
@@ -106,6 +108,7 @@ objects and arrays) for a menu with:
106
108
  | `data-runner` | `"worker"` (default) runs the code in a Web Worker. `"window"` runs it directly in the page. See below. |
107
109
  | `data-divider-orient` | `"vertical"` puts the editor beside the output and `"horizontal"` puts it below. If not specified the editor is beside the output unless the console is narrower than 600px. |
108
110
  | `data-hide-prefix` | Any block whose header starts with this prefix is hidden. See below. |
111
+ | `data-loading` | `"lazy"` (default) waits to load the console until it is about to be scrolled into view (or, if it is hidden, shown). `"eager"` loads it right away. See "Loading" below. |
109
112
  | `data-theme` | `"light"` or `"dark"`. Defaults to following the system's color scheme like the browser's dev tools. |
110
113
 
111
114
  ### Results
@@ -225,14 +228,27 @@ The About window lists the versions that each version of JS Box uses.
225
228
  `timeLog()`, `timeEnd()`, `trace()`, `group()`, `groupCollapsed()`,
226
229
  `groupEnd()` and `clear()` are all shown in the console.
227
230
 
231
+ ### Loading
232
+
233
+ Like `<img loading="lazy">`, a console isn't loaded until it is about to be
234
+ scrolled into view, so a page with many consoles (eg. a long tutorial) only
235
+ loads the ones that are read. A console that is hidden (eg. in a closed tab)
236
+ loads once it is shown. Its space in the page is kept while it waits, so
237
+ nothing moves around when it loads.
238
+
239
+ Until a console loads none of its code runs, including hidden blocks, and in
240
+ window mode the page's `console` functions aren't captured yet. Add
241
+ `data-loading="eager"` to load a console right away (eg. if its hidden blocks
242
+ set up something that the page needs).
243
+
228
244
  ### Hidden Code
229
245
 
230
246
  If `data-hide-prefix="HIDE"` is specified then a block with a header like
231
247
  `// HIDE: Setup \\` will not be shown in the editor. Instead it runs
232
- automatically as soon as all of the code that came before it has run. It shows
233
- up in the output as a collapsed block labelled with whatever came after the
234
- prefix (and optional colon), or "Hidden code" if nothing did. Clicking the
235
- label shows or hides the code.
248
+ automatically (once the console loads) as soon as all of the code that came
249
+ before it has run. It shows up in the output as a collapsed block labelled
250
+ with whatever came after the prefix (and optional colon), or "Hidden code" if
251
+ nothing did. Clicking the label shows or hides the code.
236
252
 
237
253
  ### JavaScript API
238
254
 
@@ -267,7 +283,7 @@ functions). The options are:
267
283
  | `placement` | Where the console goes: `"fill"` (default) replaces the target's contents, `"append"` and `"prepend"` add it inside of the target, `"replace"` replaces the target itself and `"before"` and `"after"` add it next to the target. |
268
284
  | `height` | The CSS height of the console (a number is treated as pixels). Defaults to `"100%"` so the console fills its container. It is never less than 150px. |
269
285
  | `code` | The code that the console starts with. |
270
- | `runner`, `blockType`, `language`, `showResults`, `hidePrefix`, `dividerOrient`, `theme`, `importsUrl`, `librariesUrl` | The same as the `data-*` attributes above. |
286
+ | `runner`, `blockType`, `language`, `showResults`, `hidePrefix`, `dividerOrient`, `theme`, `importsUrl`, `librariesUrl`, `loading` | The same as the `data-*` attributes above. |
271
287
 
272
288
  `YourJSBox.version` is the version of JS Box that was loaded.
273
289
 
@@ -309,6 +325,8 @@ Install the development dependencies by running `npm install`.
309
325
  Pages doesn't always deploy when they are pushed together), publishes to npm
310
326
  and, once npm lists the new version, purges jsDelivr's cache. Add
311
327
  `--dry-run` to see what it would do or `--skip-tests` to skip the tests.
328
+ - `npm run record-demo` records `demo.gif` (shown at the top of this README)
329
+ from the built files. It needs [ffmpeg](https://ffmpeg.org/).
312
330
  - `npm run purge-cdn` purges jsDelivr's cache so that URLs like
313
331
  `yourjs-box@1` point to the latest version right away.
314
332
  - In VS Code, **Terminal &rarr; Run Task&hellip;** has tasks for all of these
@@ -316,10 +334,42 @@ Install the development dependencies by running `npm install`.
316
334
  - `npm start` builds and then rebuilds whenever one of the files in `src/`
317
335
  changes (without serving anything).
318
336
 
319
- The kitchen sink example (`examples/kitchen-sink.html`) has several consoles
320
- which cover every feature. Add `?build=standard` or `?build=min` to its URL to
321
- test `dist/yourjs-box.js` or `dist/yourjs-box.min.js` instead of
322
- `dist/yourjs-box.full.js`.
337
+ The kitchen sink example (`examples/kitchen-sink.html`) has a sidebar for
338
+ choosing an example and every option, including which build is loaded
339
+ (`dist/yourjs-box.full.js`, `dist/yourjs-box.js` or `dist/yourjs-box.min.js`).
340
+ The options are kept in the URL so the page can be reloaded or shared as is.
341
+
342
+ ## Roadmap
343
+
344
+ Ideas for future versions, roughly from easiest to hardest:
345
+
346
+ - **Format specifiers:** support `%s`, `%d`, `%i`, `%f`, `%o`, `%O` and `%c`
347
+ (CSS styles) in `console.log()` and the other logging functions.
348
+ - **Repeated messages:** show identical messages logged in a row once with a
349
+ count, like the browser's console.
350
+ - **Run all:** run every remaining block with <kbd>Ctrl</kbd> /
351
+ <kbd>&#8984;</kbd> + <kbd>Shift</kbd> + <kbd>Enter</kbd> or from the
352
+ **&#8943;** menu.
353
+ - **`data-autorun`:** run every visible block when the page loads.
354
+ - **Clear shortcut:** clear the console with <kbd>Ctrl</kbd> + <kbd>L</kbd>.
355
+ - **Autocomplete:** turn on Ace's keyword and snippet completion in the editor.
356
+ - **`data-remember`:** save the editor's code and history in the browser so
357
+ that they are still there after a reload.
358
+ - **Copy output:** copy everything in the console as text from the **&#8943;**
359
+ menu.
360
+ - **Clickable error locations:** clicking `snippet-2.js:3:7` in an error
361
+ highlights that line in the code that ran.
362
+ - **More JavaScript API:** `box.run()`, `box.runAll()`, `box.reset()`,
363
+ `box.setCode()` and events (eg. `box.on('log', ...)`) so that a page can
364
+ control the console.
365
+ - **Output filter:** search the output and show only errors, warnings or logs.
366
+ - **Exercises:** hidden blocks that check the code above them and show which
367
+ checks passed (eg. "`sum(2, 3)` should be `5`").
368
+ - **`@timeout`:** an annotation in a block's header that runs the block
369
+ automatically once nothing has been logged for the given number of seconds.
370
+ - **Long output:** keep the console fast when thousands of messages are logged.
371
+ - **Accessibility:** announce new output to screen readers and make every value
372
+ and menu reachable with the keyboard.
323
373
 
324
374
  ## License
325
375
 
@@ -1,4 +1,4 @@
1
- /*! yourjs-box v1.7.0 | (c) 2023-present Chris West | MIT License | https://github.com/westc/yourjs-box */
1
+ /*! yourjs-box v1.8.0 | (c) 2023-present Chris West | MIT License | https://github.com/westc/yourjs-box */
2
2
  (() => {
3
3
  /**
4
4
  * Viewer IFRAME's CSS code
@@ -9,7 +9,7 @@
9
9
  * Information about this package (eg. its version).
10
10
  * @type {{name: string, version: string, homepage: string, repoUrl: string, bugsUrl: string}}
11
11
  */
12
- const PACKAGE_INFO = {"name":"yourjs-box","version":"1.7.0","homepage":"https://westc.github.io/yourjs-box/","repoUrl":"https://github.com/westc/yourjs-box","bugsUrl":"https://github.com/westc/yourjs-box/issues"};
12
+ const PACKAGE_INFO = {"name":"yourjs-box","version":"1.8.0","homepage":"https://westc.github.io/yourjs-box/","repoUrl":"https://github.com/westc/yourjs-box","bugsUrl":"https://github.com/westc/yourjs-box/issues"};
13
13
  /**
14
14
  * Viewer IFRAME's HTML code
15
15
  * @type {string}
@@ -1114,9 +1114,8 @@
1114
1114
  let popOutWatcher;
1115
1115
  let activeViewer;
1116
1116
  const sendToViewer = data => relayMessage(data, {viewer: activeViewer});
1117
- const runner = runnerMode === 'window'
1118
- ? createWindowRunner(sendToViewer)
1119
- : createWorkerRunner(sendToViewer);
1117
+ // Created once the console is loaded (see load()).
1118
+ let runner = null;
1120
1119
 
1121
1120
  // The theme is determined up front so that the loading screen uses it.
1122
1121
  const theme = /^(light|dark)$/.test(dataset.theme)
@@ -1213,6 +1212,7 @@
1213
1212
  */
1214
1213
  function createViewer(targetWindow, state) {
1215
1214
  return createCallableFrame({
1215
+ deferLoad: !targetWindow,
1216
1216
  jsCode() {
1217
1217
  let mountedApp;
1218
1218
 
@@ -3439,6 +3439,37 @@
3439
3439
  insert(inlineViewer.iframe);
3440
3440
 
3441
3441
  let isDestroyed = false;
3442
+
3443
+ /**
3444
+ * Loads the viewer and starts the runner (which, in window mode, is when
3445
+ * the page's console functions start being captured).
3446
+ */
3447
+ function load() {
3448
+ if (runner || isDestroyed) return;
3449
+ runner = runnerMode === 'window'
3450
+ ? createWindowRunner(sendToViewer)
3451
+ : createWorkerRunner(sendToViewer);
3452
+ inlineViewer.load();
3453
+ }
3454
+
3455
+ // Unless data-loading="eager" is given, nothing is loaded until the console
3456
+ // is about to be scrolled into view (or a hidden console is shown).
3457
+ /** @type {IntersectionObserver?} */
3458
+ let loadObserver = null;
3459
+ if (dataset.loading !== 'eager' && 'function' === typeof window.IntersectionObserver) {
3460
+ loadObserver = new IntersectionObserver(entries => {
3461
+ if (entries.some(entry => entry.isIntersecting)) {
3462
+ loadObserver.disconnect();
3463
+ loadObserver = null;
3464
+ load();
3465
+ }
3466
+ }, {rootMargin: '200px'});
3467
+ loadObserver.observe(inlineViewer.iframe);
3468
+ }
3469
+ else {
3470
+ load();
3471
+ }
3472
+
3442
3473
  return {
3443
3474
  element: inlineViewer.iframe,
3444
3475
  /**
@@ -3454,7 +3485,8 @@
3454
3485
  popOutWindow = null;
3455
3486
  }
3456
3487
  removeEventListener('pagehide', closePopOut);
3457
- runner.destroy();
3488
+ loadObserver?.disconnect();
3489
+ runner?.destroy();
3458
3490
  inlineViewer.dispose();
3459
3491
  inlineViewer.iframe.remove();
3460
3492
  },
@@ -3490,7 +3522,7 @@
3490
3522
  * The options of YourJSBox.create() which are the same as the data
3491
3523
  * attributes of a script tag.
3492
3524
  */
3493
- const CONSOLE_OPTION_NAMES = ['blockType', 'dividerOrient', 'hidePrefix', 'importsUrl', 'language', 'librariesUrl', 'runner', 'showResults', 'theme'];
3525
+ const CONSOLE_OPTION_NAMES = ['blockType', 'dividerOrient', 'hidePrefix', 'importsUrl', 'language', 'librariesUrl', 'loading', 'runner', 'showResults', 'theme'];
3494
3526
 
3495
3527
  /**
3496
3528
  * The JavaScript API for creating consoles (available as window.YourJSBox).
@@ -3523,6 +3555,7 @@
3523
3555
  * @param {string=} options.theme
3524
3556
  * @param {string=} options.librariesUrl
3525
3557
  * @param {string=} options.importsUrl
3558
+ * @param {string=} options.loading
3526
3559
  * The same as the data attributes of a script tag.
3527
3560
  * @returns {{element: HTMLIFrameElement, destroy: () => void}}
3528
3561
  */
@@ -3607,6 +3640,8 @@
3607
3640
  * @param {Window=} options.targetWindow
3608
3641
  * If given the page is written into this (same origin) window (eg. a
3609
3642
  * pop-out window) instead of into a new IFRAME.
3643
+ * @param {boolean=} options.deferLoad
3644
+ * If true the IFRAME's page isn't loaded until `load()` is called.
3610
3645
  * @param {((this: R, event: MessageEvent) => void)=} options.onMessage
3611
3646
  * @param {((this: R, event: MessageEvent) => void)=} options.onReady
3612
3647
  * @returns {R}
@@ -3688,9 +3723,9 @@
3688
3723
  TARGET_WINDOW.document.close();
3689
3724
  }
3690
3725
  else {
3691
- IFRAME.srcdoc = HTML_CODE;
3692
3726
  // Allows the console to go full screen.
3693
3727
  IFRAME.setAttribute('allow', 'fullscreen');
3728
+ if (!options.deferLoad) IFRAME.srcdoc = HTML_CODE;
3694
3729
  }
3695
3730
 
3696
3731
  // Set the style of the iframe.
@@ -3752,6 +3787,10 @@
3752
3787
  },
3753
3788
  iframe: IFRAME,
3754
3789
  window: TARGET_WINDOW,
3790
+ // Loads the IFRAME's page if it was deferred.
3791
+ load: function() {
3792
+ if (IFRAME && !IFRAME.srcdoc) IFRAME.srcdoc = HTML_CODE;
3793
+ },
3755
3794
  // Stops listening for messages from the frame.
3756
3795
  dispose: function() {
3757
3796
  removeEventListener('message', onWindowMessage);
@@ -3765,6 +3804,7 @@
3765
3804
  * @property {(funcName: string, ...args: any[]) => void} call
3766
3805
  * @property {HTMLIFrameElement?} iframe
3767
3806
  * @property {Window=} window
3807
+ * @property {() => void} load
3768
3808
  * @property {() => void} dispose
3769
3809
  */
3770
3810
 
@@ -1,4 +1,4 @@
1
- /*! yourjs-box v1.7.0 | (c) 2023-present Chris West | MIT License | https://github.com/westc/yourjs-box */
1
+ /*! yourjs-box v1.8.0 | (c) 2023-present Chris West | MIT License | https://github.com/westc/yourjs-box */
2
2
  (() => {
3
3
  /**
4
4
  * Viewer IFRAME's CSS code
@@ -9,7 +9,7 @@
9
9
  * Information about this package (eg. its version).
10
10
  * @type {{name: string, version: string, homepage: string, repoUrl: string, bugsUrl: string}}
11
11
  */
12
- const PACKAGE_INFO = {"name":"yourjs-box","version":"1.7.0","homepage":"https://westc.github.io/yourjs-box/","repoUrl":"https://github.com/westc/yourjs-box","bugsUrl":"https://github.com/westc/yourjs-box/issues"};
12
+ const PACKAGE_INFO = {"name":"yourjs-box","version":"1.8.0","homepage":"https://westc.github.io/yourjs-box/","repoUrl":"https://github.com/westc/yourjs-box","bugsUrl":"https://github.com/westc/yourjs-box/issues"};
13
13
  /**
14
14
  * Viewer IFRAME's HTML code
15
15
  * @type {string}
@@ -257,9 +257,8 @@
257
257
  let popOutWatcher;
258
258
  let activeViewer;
259
259
  const sendToViewer = data => relayMessage(data, {viewer: activeViewer});
260
- const runner = runnerMode === 'window'
261
- ? createWindowRunner(sendToViewer)
262
- : createWorkerRunner(sendToViewer);
260
+ // Created once the console is loaded (see load()).
261
+ let runner = null;
263
262
 
264
263
  // The theme is determined up front so that the loading screen uses it.
265
264
  const theme = /^(light|dark)$/.test(dataset.theme)
@@ -356,6 +355,7 @@
356
355
  */
357
356
  function createViewer(targetWindow, state) {
358
357
  return createCallableFrame({
358
+ deferLoad: !targetWindow,
359
359
  jsCode() {
360
360
  let mountedApp;const IS_MISSING_LIBRARIES=!window.Vue||!window.ace||!window.Prism;IS_MISSING_LIBRARIES&&document.querySelector("#splash").classList.add("failed");const Prism=window.Prism;delete window.Prism,Prism?.plugins.autoloader.loadLanguages("javascript");const MIN_LOADING_TIME=1e3,POP_IN_FUNCTION_NAME="yourjsBoxPopIn",TEXT_SCALES=[.75,.9,1,1.15,1.3,1.5,1.75,2],TEXT_SCALE_STORAGE_KEY="yourjs-box.textScale";function loadTextScale(){try{const e=+localStorage.getItem(TEXT_SCALE_STORAGE_KEY);return TEXT_SCALES.includes(e)?e:1}catch(e){return 1}}const NARROW_WIDTH=600;function getAutoDividerOrient(){return innerWidth<NARROW_WIDTH?"horizontal":"vertical"}function init(e,t,i){if(IS_MISSING_LIBRARIES)return;if("typescript"===i.language&&!window.Babel)return void document.querySelector("#splash").classList.add("failed");Prism.plugins.autoloader.loadLanguages(i.language);const s=t.hidePrefix??"",o=matchMedia("(prefers-color-scheme: dark)"),r=unindentMin(e),{visibleCode:n,hiddenGroups:a}=extractHiddenGroups(r,s),l=/Mac|iPhone|iPad/.test(navigator.platform);mountedApp=Vue.createApp({data:()=>({displays:[],hidePrefix:s,hiddenGroups:a.map((e=>({...e}))),runnerMode:i.runnerMode,importsUrl:i.importsUrl,originalCode:r,fileName:null,blockType:i.blockType,language:i.language,showResults:i.showResults,packageInfo:i.packageInfo,libraryVersions:i.libraryVersions,runHistory:[],isAboutOpen:!1,aboutTab:"about",exportCode:"current",exportFormat:"snippet",copyLabel:"Copy",runningCount:0,dialog:null,isDisplaysScrolledToBottom:!0,forcedTheme:/^(light|dark)$/.test(t.theme)?t.theme:null,prefersDark:o.matches,runCount:0,jsCode:n,isDividerOrientAuto:!/^(horizontal|vertical)$/.test(t.dividerOrient),dividerOrient:/^(horizontal|vertical)$/.test(t.dividerOrient)?t.dividerOrient:getAutoDividerOrient(),isMovingDivider:!1,dividerPct:"50%",dividerSize:"8px",tempDividerPct:null,isMenuOpen:!1,isHistoryOpen:!1,commandHistory:[],historyIndex:null,historyDraft:null,valueMenu:null,toast:null,textScale:loadTextScale(),isFullscreen:!1,isMaximized:!1,isPopOut:i.isPopOut,isPoppedOut:!1,...i.popOutState??{}}),computed:{theme(){return this.forcedTheme??(this.prefersDark?"dark":"light")},modKey:()=>l?"\u2318":"Ctrl",runnerDescription(){return"window"===this.runnerMode?"This page (it can use the page's globals and DOM)":"A Web Worker (isolated from the page, no DOM)"},themeDescription(){return`${"dark"===this.theme?"Dark":"Light"} (${this.forcedTheme?"set by data-theme":"follows your system"})`},isTypeScript(){return"typescript"===this.language},builtWith(){const e=this.libraryVersions,t=[`Vue ${e.vue}`,`Ace ${e["ace-builds"]}`,`Prism ${e.prismjs}`,`Acorn ${e.acorn}`,...this.isTypeScript?[`Babel ${e["@babel/standalone"]}`]:[]];return t.slice(0,-1).join(", ")+" and "+t[t.length-1]},blockTypeDescription(){return"module"===this.blockType?"Modules (top-level await and imports work, declarations stay in each block)":"Classic scripts (top-level declarations are shared between blocks)"},collapsedGroupIds(){return new Set(this.displays.filter((e=>e.groupId&&e.isCollapsed)).map((e=>e.groupId)))},layoutDescription(){return("vertical"===this.dividerOrient?"Editor beside the console":"Editor below the console")+(this.isDividerOrientAuto?" (automatic)":"")},exportCodeOptions:()=>[{value:"current",label:"Current code",note:"The code that already ran followed by the code in the editor."},{value:"original",label:"Original code",note:"The code this console started with."},{value:"blank",label:"Blank",note:"An empty console with the same settings."}],exportFormatOptions:()=>[{value:"snippet",label:"Embed snippet"},{value:"page",label:"Full page"}],exportNote(){return this.exportCodeOptions.find((e=>e.value===this.exportCode)).note},originalGroups(){return extractHiddenGroups(this.originalCode,this.hidePrefix)},exportJsCode(){return"original"===this.exportCode?this.originalCode:"blank"===this.exportCode?"":this.currentCode},currentCode(){const e=this.runHistory.slice(),t=this.hiddenGroups.slice();let i=this.runCount;const s=()=>{for(;t.length&&t[0].runCount<=i;)e.push(t.shift().allLines)};s();for(const t of parseJSCodeGroups(this.jsCode))t.allLines.trim()&&(e.push(t.allLines),i++,s());return e.push(...t.map((e=>e.allLines))),joinCodeBlocks(e)},exportDataset(){const{librariesUrl:e,...i}=t;return i},exportHtml(){return buildConsoleHtml({code:this.exportJsCode,dataset:this.exportDataset,packageInfo:this.packageInfo,isFullPage:"page"===this.exportFormat})},bottomButtons(){const e=this.isFullscreen||this.isMaximized;return[{iconName:"more",title:"More",className:"more-button",callback(){this.toggleMenu()}},{iconName:"clear",title:"Clear console",callback(){this.clearConsole()}},{iconName:"history",title:`History (${l?"\u2325":"Alt+"}H)`,className:"history-button",callback(){this.toggleHistory()}},{iconName:"horizontalView",title:"Show the editor below the console",callback(){this.setDividerOrient("horizontal")},showIf(){return"horizontal"!==this.dividerOrient}},{iconName:"verticalView",title:"Show the editor beside the console",callback(){this.setDividerOrient("vertical")},showIf(){return"vertical"!==this.dividerOrient}},{iconName:e?"exitFullscreen":"fullscreen",title:e?"Exit full screen":"Full screen",callback(){this.toggleFullscreen()}},{iconName:this.runningCount?"spinner":"play",label:"Run",className:"primary",title:`Run the next block of code (${l?"\u2318":"Ctrl+"}Enter)`,callback(){this.runCode()},disableIf(){return!this.canRunCode}}].filter((e=>!e.showIf||e.showIf.call(this)))},historyEntries(){return this.commandHistory.map(((e,t)=>{const[i]=parseJSCodeGroups(e),s=(i?.lines??e).split("\n").filter((e=>e.trim()));return{index:t,label:i?.headerLines||s[0]||"",detail:`${s.length} line${1===s.length?"":"s"}`}})).reverse()},canShrinkText(){return this.textScale>TEXT_SCALES[0]},canGrowText(){return this.textScale<TEXT_SCALES[TEXT_SCALES.length-1]},canRunCode(){return this.jsCode.trim()},mainElemClassNames(){return["vertical"===this.dividerOrient?"col-orient":"row-orient",this.isMovingDivider?"is-moving-divider":""].join(" ")},mainElemStyles(){return{"--divider-size":this.dividerSize,"--editor-pct":this.dividerPct,"--temp-editor-pct":this.tempDividerPct}}},methods:{onEditorKeyCombo(e){(e.ctrlKey||e.metaKey)&&"Enter"===e.key&&this.canRunCode&&this.runCode()},runCode(){this.isDisplaysScrolledToBottom=!0;const[e,...t]=parseJSCodeGroups(this.jsCode);this.runGroup(e);const i=t.map((e=>e.allLines)).join("\n");null!==this.historyIndex?(this.jsCode=[i,this.historyDraft].filter((e=>e.trim())).join("\n"),this.historyIndex=this.historyDraft=null):(this.jsCode=i,this.runCount++)},navigateHistory(e){const t=this.commandHistory;if(e<0)return!!t.length&&(null===this.historyIndex&&(this.historyDraft=this.jsCode,this.historyIndex=t.length),this.historyIndex>0&&this.showHistoryCode(this.historyIndex-1,"start"),!0);if(null===this.historyIndex)return!1;if(this.historyIndex<t.length-1)this.showHistoryCode(this.historyIndex+1,"end");else{const e=this.historyDraft;this.historyIndex=this.historyDraft=null,this.setEditorCode(e,"end")}return!0},showHistoryCode(e,t){null===this.historyIndex&&(this.historyDraft=this.jsCode),this.historyIndex=e,this.setEditorCode(this.commandHistory[e],t)},setEditorCode(e,t){this.jsCode=e,this.$nextTick((()=>{const e=this.$refs.editor?.editor;e&&("end"===t?e.navigateFileEnd():e.navigateFileStart())}))},onEditorHistoryKey(e){e.handled=this.navigateHistory(e.direction)},toggleHistory(){this.isHistoryOpen?this.isHistoryOpen=!1:(this.closeMenu(),this.closeValueMenu(),this.isHistoryOpen=!0,this.$nextTick((()=>this.$refs.historyPanel?.querySelector(".menu-item")?.focus())))},recallHistory(e){this.isHistoryOpen=!1,this.showHistoryCode(e,"start"),this.$nextTick((()=>this.$refs.editor?.editor.focus()))},stopNavigatingHistory(){this.historyIndex=this.historyDraft=null},runHiddenGroups(){const{hiddenGroups:e}=this;e.length&&e[0].runCount<=this.runCount&&this.runGroup(e.shift())},runGroup(e){const{header:t,isHidden:i}=parseGroupHeader(e.headerLines,this.hidePrefix);this.displays.push({type:"prism",header:t,isHidden:i,isCodeShown:!i,value:e.lines}),this.runningCount++,this.runHistory.push(e.allLines);const s=e.allLines.trim();!i&&s&&this.commandHistory[this.commandHistory.length-1]!==s&&(this.commandHistory.push(s),this.commandHistory.length>200&&this.commandHistory.shift());const{language:o,blockType:r}=this,n="typescript"===o?compileTypeScript(e.lines,{blockType:r}):{code:e.lines},{code:a,resultRange:l}=n.error?{code:"",resultRange:null}:prepareCode(n.code,{blockType:r,importsUrl:this.importsUrl,findResult:this.showResults&&!i});messageParent({target:"runner",func:"runCode",args:[a,{blockType:r,resultRange:l,language:o,sourceMap:n.sourceMap,compileError:n.error}]})},clearConsole(){this.displays=[],messageParent({target:"runner",func:"clearLogs",args:[]})},async resetConsole(){await this.confirm({title:"Reset the console?",message:"The output will be cleared and the editor will go back to the original code."+("window"===this.runnerMode?" Anything the code already defined on the page will stay defined.":""),confirmText:"Reset"})&&this.restart()},restart(){const{visibleCode:e,hiddenGroups:t}=this.originalGroups;this.displays=[],this.jsCode=e,this.hiddenGroups=t.map((e=>({...e}))),this.runCount=0,this.runningCount=0,this.runHistory=[],this.stopNavigatingHistory(),messageParent({target:"runner",func:"reset",args:[]}),this.runHiddenGroups()},openFile(){this.closeMenu();const{fileInput:e}=this.$refs;e.value="",e.click()},async onFileChosen(e){const t=e.target.files?.[0];if(!t)return;const i=unindentMin(await t.text());if(this.displays.length||this.jsCode.trim()){if(!await this.confirm({title:`Open ${t.name}?`,message:"The output will be cleared and the code in the editor will be replaced with the code in the file."+("window"===this.runnerMode?" Anything the code already defined on the page will stay defined.":""),confirmText:"Open"}))return}this.fileName=t.name,this.originalCode=i,this.restart()},async saveFile(){this.closeMenu();const e=this.currentCode+"\n",t=this.fileName||(this.isTypeScript?"js-box.ts":"js-box.js"),i=this.isTypeScript?{description:"TypeScript",accept:{"text/typescript":[".ts",".mts"]}}:{description:"JavaScript",accept:{"text/javascript":[".js",".mjs"]}};if("function"==typeof window.showSaveFilePicker)try{const s=await showSaveFilePicker({suggestedName:t,types:[i]}),o=await s.createWritable();return await o.write(e),await o.close(),void(this.fileName=s.name)}catch(e){if("AbortError"===e?.name)return}const s=URL.createObjectURL(new Blob([e],{type:Object.keys(i.accept)[0]}));Object.assign(document.createElement("a"),{href:s,download:t}).click(),setTimeout((()=>URL.revokeObjectURL(s)),1e3)},async copyToEditor(e){if(this.jsCode.trim()&&this.jsCode!==e){if(!await this.confirm({title:"Replace the code in the editor?",message:"The code that is currently in the editor will be replaced with a copy of the code you selected.",confirmText:"Replace"}))return}this.stopNavigatingHistory(),this.jsCode=e},confirm(e){return this.dialog?.resolve(!1),new Promise((t=>{this.dialog={...e,resolve:t},this.$nextTick((()=>this.$refs.dialogConfirmButton?.focus()))}))},openAbout(e){this.aboutTab=e,this.isAboutOpen=!0,this.$nextTick((()=>this.$refs.aboutCloseButton?.focus()))},closeAbout(){this.isAboutOpen=!1},async copyExport(){const e=this.exportHtml;try{await navigator.clipboard.writeText(e)}catch(t){const i=Object.assign(document.createElement("textarea"),{value:e});document.body.appendChild(i),i.select(),document.execCommand("copy"),i.remove()}this.copyLabel="Copied!",clearTimeout(this.copyLabelTimeout),this.copyLabelTimeout=setTimeout((()=>this.copyLabel="Copy"),1600)},downloadExport(){const e=buildConsoleHtml({code:this.exportJsCode,dataset:this.exportDataset,packageInfo:this.packageInfo,isFullPage:!0}),t=URL.createObjectURL(new Blob([e],{type:"text/html"}));Object.assign(document.createElement("a"),{href:t,download:"js-box.html"}).click(),setTimeout((()=>URL.revokeObjectURL(t)),1e3)},onLogRowClick(e,t){e.groupId&&!t.target.closest(".js-value-header.expandable")&&(e.isCollapsed=!e.isCollapsed)},isInCollapsedGroup(e){const{collapsedGroupIds:t}=this;return!!t.size&&!!e.groupIds?.some((e=>t.has(e)))},getState(){return JSON.parse(JSON.stringify({displays:this.displays,jsCode:this.jsCode,originalCode:this.originalCode,fileName:this.fileName,commandHistory:this.commandHistory,historyIndex:this.historyIndex,historyDraft:this.historyDraft,runHistory:this.runHistory,hiddenGroups:this.hiddenGroups,runCount:this.runCount,runningCount:this.runningCount,dividerOrient:this.dividerOrient,isDividerOrientAuto:this.isDividerOrientAuto,dividerPct:this.dividerPct}))},restoreState(e){Object.assign(this,e),this.isDisplaysScrolledToBottom=!0},toggleMenu(){this.isMenuOpen?this.closeMenu():(this.isHistoryOpen=!1,this.closeValueMenu(),this.isMenuOpen=!0,this.$nextTick((()=>this.$refs.moreMenu?.querySelector(".menu-item:not(:disabled)")?.focus())))},closeMenu(e){this.isMenuOpen=!1,e&&document.querySelector("#bottomNav .more-button")?.focus()},onMenuKeyDown(e){if("Escape"===e.key)e.stopPropagation(),this.closeMenu(this.isMenuOpen),this.closeValueMenu(),this.isHistoryOpen=!1;else if("ArrowDown"===e.key||"ArrowUp"===e.key){e.preventDefault();const t=[...e.currentTarget.querySelectorAll(".menu-item:not(:disabled)")],i=t.indexOf(document.activeElement),s=t[(i+("ArrowDown"===e.key?1:t.length-1))%t.length];s?.focus()}},changeTextScale(e){const t=TEXT_SCALES.indexOf(this.textScale)+e;t>=0&&t<TEXT_SCALES.length&&this.setTextScale(TEXT_SCALES[t])},setTextScale(e){this.textScale=e;try{localStorage.setItem(TEXT_SCALE_STORAGE_KEY,`${e}`)}catch(e){}},async toggleFullscreen(){if(this.isMaximized)this.setMaximized(!1);else if(document.fullscreenElement)await document.exitFullscreen();else try{await document.documentElement.requestFullscreen()}catch(e){this.isPopOut||this.setMaximized(!0)}},setMaximized(e){this.isMaximized=e,messageParent({target:"host",func:"setMaximized",args:[e]})},popOut(){this.closeMenu(),this.isMaximized&&this.setMaximized(!1),messageParent({target:"host",func:"popOut",args:[this.getState()]})},bringBack(){this.hasSentState=!0;const e=window.yourjsBoxPopIn;"function"==typeof e?e(this.getState()):messageParent({target:"host",func:"popIn",args:[this.getState()]})},focusPopOut(){messageParent({target:"host",func:"focusPopOut",args:[]})},requestPopIn(){messageParent({target:"host",func:"requestPopIn",args:[]})},onWindowMouseDown(e){this.isMenuOpen&&!e.target.closest(".more-menu, .more-button")&&this.closeMenu(),this.valueMenu&&!e.target.closest(".value-menu")&&this.closeValueMenu(),this.isHistoryOpen&&!e.target.closest(".history-panel, .history-button")&&(this.isHistoryOpen=!1)},onWindowKeyDown(e){if(e.altKey&&!e.ctrlKey&&!e.metaKey&&"KeyH"===e.code)return e.preventDefault(),e.stopPropagation(),void this.toggleHistory();"Escape"===e.key&&this.valueMenu?this.closeValueMenu():"Escape"!==e.key||!this.isMaximized||this.isMenuOpen||this.dialog||this.isAboutOpen||this.setMaximized(!1)},openValueMenu(e,{path:t,keyPath:i,isPrimitive:s}){this.closeMenu(),this.valueMenu={x:e.clientX,y:e.clientY,path:t.slice(),propertyPath:i?.length?formatPropertyPath(i):null,fileName:i?.length&&/^[\w$-]+$/.test(i[i.length-1])?i[i.length-1]:"value",isPrimitive:s},this.$nextTick((()=>{const e=this.$refs.valueMenu;if(!e||!this.valueMenu)return;const{width:t,height:i}=e.getBoundingClientRect();this.valueMenu.x=Math.max(4,Math.min(this.valueMenu.x,innerWidth-t-4)),this.valueMenu.y=Math.max(4,Math.min(this.valueMenu.y,innerHeight-i-4)),e.querySelector(".menu-item")?.focus()}))},closeValueMenu(){this.valueMenu=null},requestValueJson(e){const t=`${Date.now()}-${Math.random()}`;return new Promise((i=>{jsonRequests.set(t,i),messageParent({target:"runner",func:"getValueAsJson",args:[e,t]})}))},showToast(e){clearTimeout(this.toastTimeout),this.toast={message:e},this.toastTimeout=setTimeout((()=>this.toast=null),3500)},showJsonToast({circularCount:e,error:t},i){this.showToast(t||i+(e?` (${e} circular reference${1===e?" was":"s were"} left out)`:""))},async copyValueAsJson(){const e=[...this.valueMenu.path];this.closeValueMenu();const t=this.requestValueJson(e);try{if(window.ClipboardItem&&navigator.clipboard?.write)await navigator.clipboard.write([new ClipboardItem({"text/plain":t.then((({json:e,error:t})=>{if(t)throw new Error(t);return new Blob([e],{type:"text/plain"})}))})]);else{const{json:e,error:i}=await t;if(i)throw new Error(i);await navigator.clipboard.writeText(e)}this.showJsonToast(await t,"Copied as JSON")}catch(e){const i=await t;this.showToast(i.error||"The value couldn't be copied. Your browser may not allow copying here.")}},async saveValueAsJson(){const{fileName:e}=this.valueMenu,t=[...this.valueMenu.path];this.closeValueMenu();const i=this.requestValueJson(t),s=`${e}.json`;let o;if("function"==typeof window.showSaveFilePicker)try{o=await showSaveFilePicker({suggestedName:s,types:[{description:"JSON",accept:{"application/json":[".json"]}}]})}catch(e){if("AbortError"===e?.name)return}const r=await i;if(r.error)return void this.showToast(r.error);const n=r.json+"\n";if(o){const e=await o.createWritable();await e.write(n),await e.close()}else{const e=URL.createObjectURL(new Blob([n],{type:"application/json"}));Object.assign(document.createElement("a"),{href:e,download:s}).click(),setTimeout((()=>URL.revokeObjectURL(e)),1e3)}this.showJsonToast(r,"Saved as JSON")},storeValueAsGlobal(){const e=[...this.valueMenu.path];this.closeValueMenu(),messageParent({target:"runner",func:"storeAsGlobal",args:[e]})},async copyPropertyPath(){const{propertyPath:e}=this.valueMenu;this.closeValueMenu();try{await navigator.clipboard.writeText(e),this.showToast(`Copied ${e}`)}catch(e){this.showToast("The property path couldn't be copied. Your browser may not allow copying here.")}},refreshValue(){const e=[...this.valueMenu.path];this.closeValueMenu(),messageParent({target:"runner",func:"refreshDescription",args:[e]})},closeDialog(e){const{dialog:t}=this;this.dialog=null,t?.resolve(e)},setDividerOrient(e){this.isDividerOrientAuto=!1,this.dividerOrient=e},onWindowResize(){this.isDividerOrientAuto&&(this.dividerOrient=getAutoDividerOrient())},onDisplaysScroll(){this.closeValueMenu();const{scrollTop:e,scrollHeight:t,clientHeight:i}=this.$refs.displaysScroller;this.isDisplaysScrolledToBottom=t-e-i<8},getEditorPct(e){const t=this.$refs.main.getBoundingClientRect(),{dividerOrient:i}=this,s=e.pageX-t.left,o=e.pageY-t.top,r=t.width,n=t.height;return 100-100*Math.min(Math.max(.2,"vertical"===i?s/r:o/n),.8)+"%"},onMainElemMouseDown(e){e.target===this.$refs.mainDivider&&(this.isMovingDivider=!0,this.tempDividerPct=this.getEditorPct(e))},onWindowMouseMove(e){this.isMovingDivider&&(this.tempDividerPct=this.getEditorPct(e))},onWindowMouseUp(e){this.isMovingDivider&&(this.isMovingDivider=!1,this.dividerPct=this.getEditorPct(e))},onWindowError(e){this.displays.push({type:"error",message:e.error?.stack??e.message??e.error?.message??`${e.error}`,line:e.lineno,column:e.colno})}},watch:{textScale:{handler(e){document.documentElement.style.setProperty("--text-scale",e)},immediate:!0},theme:{handler(e){document.documentElement.dataset.theme=e},immediate:!0},"displays.length"(){this.isDisplaysScrolledToBottom&&this.$nextTick((()=>{const e=this.$refs.displaysScroller;e.scrollTop=e.scrollHeight}))}},mounted(){addEventListener("mousemove",this.onWindowMouseMove),addEventListener("mousedown",this.onWindowMouseDown),addEventListener("keydown",this.onWindowKeyDown,!0),addEventListener("resize",this.onWindowResize),addEventListener("mouseup",this.onWindowMouseUp),addEventListener("error",this.onWindowError),o.addEventListener("change",(e=>this.prefersDark=e.matches)),document.addEventListener("fullscreenchange",(()=>this.isFullscreen=!!document.fullscreenElement)),this.isPopOut&&addEventListener("pagehide",(()=>this.hasSentState||this.bringBack())),this.runningCount||this.runHiddenGroups(),setTimeout((()=>document.querySelector("#splash").classList.add("hidden")),Math.max(0,(this.isPopOut?0:1e3)-performance.now()))}}).component("ace-editor",getAceComponentProps()).component("prism",getPrismComponentProps()).component("icon",getIconComponentProps()).component("js-value",getJSValueComponentProps()).mount(document.querySelector("#vueApp"))}function getAceComponentProps(){return{data:()=>({annotations:[]}),props:["fontSize","height","keybinding","language","modelValue","readOnly","theme","width"],computed:{infoNotes(){return this.annotations.filter((({type:e})=>"info"===e))},warningNotes(){return this.annotations.filter((({type:e})=>"warning"===e))},errorNotes(){return this.annotations.filter((({type:e})=>"error"===e))},style(){return{height:null!=this.height?"number"==typeof this.height?this.height+"px":this.height:"150px",width:null!=this.width?"number"==typeof this.width?this.width+"px":this.width:"100%"}},modeSig(){return`ace/mode/${this.language??"text"}`},themeSig(){return`ace/theme/${`${this.theme??"light"}`.replace(/^light$|(^dark$)/i,((e,t)=>"cloud_editor"+(t?"_dark":"")))}`}},watch:{themeSig(e){this.editor.setTheme(e)},fontSize(e){e&&this.editor.setFontSize(e)},modelValue(e){e!==this.editor.getValue()&&this.editor.setValue(e,-1)}},async mounted(){const e=ace.edit(this.$refs.editor,{value:this.modelValue,mode:this.modeSig,theme:this.themeSig});this.editor=e,this.fontSize&&e.setFontSize(this.fontSize),this.readOnly&&(e.setReadOnly(!0),e.setHighlightActiveLine(!1),e.session.setUseWorker(!1)),e.setKeyboardHandler("ace/keyboard/vscode"),e.commands.removeCommand("addLineAfter"),e.commands.removeCommand("addLineBefore"),e.on("change",(()=>this.$emit("update:modelValue",e.getValue()))),e.session.on("changeAnnotation",(()=>{const t=JSON.stringify(this.errorNotes),i=JSON.stringify(this.infoNotes),s=JSON.stringify(this.warningNotes);this.annotations=e.getSession().getAnnotations();const{errorNotes:o,infoNotes:r,warningNotes:n}=this;t!==JSON.stringify(o)&&this.$emit("changeErrorNotes",o),i!==JSON.stringify(r)&&this.$emit("changeInfoNotes",r),s!==JSON.stringify(n)&&this.$emit("changeWarningNotes",n)})),this.$refs.editor.addEventListener("keydown",(t=>{const i="ArrowUp"===t.key;if(!i&&"ArrowDown"!==t.key)return;if(t.shiftKey||t.altKey||t.ctrlKey||t.metaKey||!e.selection.isEmpty())return;const{row:s,column:o}=e.getCursorPosition(),r=e.session.getLength()-1;if(!(i?0===s&&0===o:s===r&&o===e.session.getLine(r).length))return;const n={direction:i?-1:1,handled:!1};this.$emit("historyKey",n),n.handled&&(t.preventDefault(),t.stopPropagation())}),!0),e.textInput.getElement().addEventListener("keydown",(e=>{if(16===e.keyCode||17===e.keyCode||18===e.keyCode||91===e.keyCode||92===e.keyCode||93===e.keyCode)return;(e.metaKey||e.ctrlKey||e.altKey||e.shiftKey&&(e.key??"").length>1)&&this.$emit("keyCombo",e)}))},template:'<div ref="editor" :style="style"></div>'}}function getPrismComponentProps(){return{data:()=>({annotations:[]}),props:["code","isDark","language","lineNumbers","matchBraces"],computed:{html(){},preStyle(){return{filter:!1!==(this.isDark??!1)?"none":"invert(1) hue-rotate(180deg) brightness(1.1)",margin:0,paddingTop:"0.5em",paddingBottom:"0.5em"}}},watch:{code(){this.redraw()},language(){this.redraw()},lineNumbers(){this.redraw()},matchBraces(){this.redraw()}},methods:{async redraw(){const e=this.$refs.pre,t=this.$refs.code;t.textContent=this.code,t.className=`language-${this.language??"javascript"}`,e.className="";for(const t of["lineNumbers","matchBraces"])if(null!=this[t]){const i=t.replace(/[A-Z]+/g,"-$&").toLowerCase();e.className+=" "+i}Prism.highlightElement(t)}},async mounted(){await this.redraw()},template:'<pre ref="pre" :style="preStyle"><code ref="code"></code></pre>'}}function getIconComponentProps(){return{props:["name"],computed:{svgCode(){const e={missing:'<svg viewBox="0 0 32 32"><circle cx="16" cy="22.5" r="1.5" fill="currentColor"/><path fill="currentColor" d="M17 19h-2v-4h2c1.103 0 2-.897 2-2s-.897-2-2-2h-2c-1.103 0-2 .897-2 2v.5h-2V13c0-2.206 1.794-4 4-4h2c2.206 0 4 1.794 4 4s-1.794 4-4 4z"/><path fill="currentColor" d="M29.391 14.527L17.473 2.609A2.078 2.078 0 0 0 16 2c-.533 0-1.067.203-1.473.609L2.609 14.527C2.203 14.933 2 15.466 2 16s.203 1.067.609 1.473L14.526 29.39c.407.407.941.61 1.474.61s1.067-.203 1.473-.609L29.39 17.474c.407-.407.61-.94.61-1.474s-.203-1.067-.609-1.473M16 28.036L3.965 16L16 3.964L28.036 16z"/></svg>',trash:'<svg viewBox="0 0 15 15"><path fill="currentColor" fill-rule="evenodd" d="M5.5 1a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1zM3 3.5a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 0 1H11v8a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V4h-.5a.5.5 0 0 1-.5-.5M5 4h5v8H5z" clip-rule="evenodd"/></svg>',play:'<svg viewBox="0 0 15 15"><path fill="currentColor" fill-rule="evenodd" d="M3.242 2.322a.5.5 0 0 1 .491-.014l9 4.75a.5.5 0 0 1 0 .884l-9 4.75A.5.5 0 0 1 3 12.25v-9.5a.5.5 0 0 1 .242-.428M4 3.579v7.842L11.429 7.5z" clip-rule="evenodd"/></svg>',refresh:'<svg viewBox="0 0 15 15"><path fill="currentColor" fill-rule="evenodd" d="M1.903 7.297c0 3.044 2.207 5.118 4.686 5.547a.521.521 0 1 1-.178 1.027C3.5 13.367.861 10.913.861 7.297c0-1.537.699-2.745 1.515-3.663c.585-.658 1.254-1.193 1.792-1.602H2.532a.5.5 0 0 1 0-1h3a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-1 0V2.686l-.001.002c-.572.43-1.27.957-1.875 1.638c-.715.804-1.253 1.776-1.253 2.97m11.108.406c0-3.012-2.16-5.073-4.607-5.533a.521.521 0 1 1 .192-1.024c2.874.54 5.457 2.98 5.457 6.557c0 1.537-.699 2.744-1.515 3.663c-.585.658-1.254 1.193-1.792 1.602h1.636a.5.5 0 1 1 0 1h-3a.5.5 0 0 1-.5-.5v-3a.5.5 0 1 1 1 0v1.845h.002c.571-.432 1.27-.958 1.874-1.64c.715-.803 1.253-1.775 1.253-2.97" clip-rule="evenodd"/></svg>',horizontalView:'<svg viewBox="0 0 15 15"><path fill="currentColor" fill-rule="evenodd" d="M1.5 2h12a.5.5 0 0 1 .5.5V7H1V2.5a.5.5 0 0 1 .5-.5M1 8v4.5a.5.5 0 0 0 .5.5h12a.5.5 0 0 0 .5-.5V8zM0 2.5A1.5 1.5 0 0 1 1.5 1h12A1.5 1.5 0 0 1 15 2.5v10a1.5 1.5 0 0 1-1.5 1.5h-12A1.5 1.5 0 0 1 0 12.5z" clip-rule="evenodd"/></svg>',verticalView:'<svg viewBox="0 0 15 15"><path fill="currentColor" fill-rule="evenodd" d="M8 2h5.5a.5.5 0 0 1 .5.5v10a.5.5 0 0 1-.5.5H8zM7 2H1.5a.5.5 0 0 0-.5.5v10a.5.5 0 0 0 .5.5H7zm-7 .5A1.5 1.5 0 0 1 1.5 1h12A1.5 1.5 0 0 1 15 2.5v10a1.5 1.5 0 0 1-1.5 1.5h-12A1.5 1.5 0 0 1 0 12.5z" clip-rule="evenodd"/></svg>',play:'<svg viewBox="0 0 16 16"><path fill="currentColor" d="M2 1v14l12-7z"/></svg>',error:'<svg viewBox="0 0 24 24"><path fill="currentColor" d="M11 15h2v2h-2zm0-8h2v6h-2zm1-5C6.47 2 2 6.5 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 18a8 8 0 0 1-8-8a8 8 0 0 1 8-8a8 8 0 0 1 8 8a8 8 0 0 1-8 8"/></svg>',history:'<svg viewBox="0 0 16 16"><path d="M2.5 8a5.5 5.5 0 1 0 1.6-3.9" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><path d="M2.25 2.5v2.75H5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M8 5v3.25l2.25 1.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',copy:'<svg viewBox="0 0 16 16"><rect x="5.5" y="5.5" width="8" height="8" rx="1.25" fill="none" stroke="currentColor" stroke-width="1.4"/><path d="M10.5 3.5v-.75A1.25 1.25 0 0 0 9.25 1.5h-5A1.25 1.25 0 0 0 3 2.75v5A1.25 1.25 0 0 0 4.25 9h.75" fill="none" stroke="currentColor" stroke-width="1.4"/></svg>',variable:'<svg viewBox="0 0 16 16"><path d="M5 2.5c-1.5 1.5-2 3.5-2 5.5s.5 4 2 5.5M11 2.5c1.5 1.5 2 3.5 2 5.5s-.5 4-2 5.5M6.5 6l3 4M9.5 6l-3 4" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>',path:'<svg viewBox="0 0 16 16"><circle cx="3.5" cy="12.5" r="1.5" fill="currentColor"/><circle cx="12.5" cy="3.5" r="1.5" fill="currentColor"/><path d="M3.5 11V8a2 2 0 0 1 2-2h5a2 2 0 0 0 2-2" fill="none" stroke="currentColor" stroke-width="1.4"/></svg>',open:'<svg viewBox="0 0 16 16"><path d="M2 4.5a1 1 0 0 1 1-1h3.2l1.3 1.5H13a1 1 0 0 1 1 1V12a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/></svg>',save:'<svg viewBox="0 0 16 16"><path d="M8 2.5v7M5 7l3 3 3-3M3 11.5v1.5h10v-1.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',fullscreen:'<svg viewBox="0 0 16 16"><path d="M2.5 6V2.5H6M10 2.5h3.5V6M13.5 10v3.5H10M6 13.5H2.5V10" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',exitFullscreen:'<svg viewBox="0 0 16 16"><path d="M6 2.5V6H2.5M13.5 6H10V2.5M10 13.5V10h3.5M2.5 10H6v3.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',more:'<svg viewBox="0 0 16 16"><circle cx="3.5" cy="8" r="1.4" fill="currentColor"/><circle cx="8" cy="8" r="1.4" fill="currentColor"/><circle cx="12.5" cy="8" r="1.4" fill="currentColor"/></svg>',popOut:'<svg viewBox="0 0 16 16"><path d="M9.5 2.5h4v4M13.5 2.5L8 8M12 9.5v3a1 1 0 0 1-1 1H3.5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h3" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',popIn:'<svg viewBox="0 0 16 16"><path d="M12 8.5H8V4.5M8 8.5l5.5-5.5M12 10.5v2a1 1 0 0 1-1 1H3.5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h2" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',code:'<svg viewBox="0 0 16 16"><path d="M5.5 4.5L2 8l3.5 3.5M10.5 4.5L14 8l-3.5 3.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',info:'<svg viewBox="0 0 16 16"><circle cx="8" cy="8" r="6.25" fill="none" stroke="currentColor" stroke-width="1.5"/><path d="M8 7.25v4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="8" cy="5" r="1" fill="currentColor"/></svg>',result:'<svg viewBox="0 0 16 16"><path d="M9 4.5L5.5 8 9 11.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><circle cx="12" cy="8" r="1.1" fill="currentColor"/></svg>',close:'<svg viewBox="0 0 16 16"><path d="M4 4l8 8m0-8l-8 8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>',clear:'<svg viewBox="0 0 16 16"><circle cx="8" cy="8" r="6" fill="none" stroke="currentColor" stroke-width="1.5"/><path d="M3.75 12.25l8.5-8.5" stroke="currentColor" stroke-width="1.5"/></svg>',copyToEditor:'<svg viewBox="0 0 16 16"><path d="M6 3.5L2.5 7 6 10.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 7h6.5a4 4 0 0 1 4 4v1.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>',spinner:'<svg viewBox="0 0 16 16" class="spin"><path d="M8 1.75a6.25 6.25 0 1 1-6.25 6.25" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round"/></svg>',chevron:'<svg viewBox="0 0 16 16"><path d="M6 4l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',consoleError:'<svg viewBox="0 0 16 16"><circle cx="8" cy="8" r="7" fill="currentColor"/><path d="M5.5 5.5l5 5m0-5l-5 5" stroke="#fff" stroke-width="1.75" stroke-linecap="round"/></svg>',consoleWarning:'<svg viewBox="0 0 16 16"><path d="M8 1.75L14.75 14H1.25z" fill="currentColor" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M8 6v3.5" stroke="#202124" stroke-width="1.75" stroke-linecap="round"/><circle cx="8" cy="11.75" r="1" fill="#202124"/></svg>'};return(e[this.name]??e.missing).replace("<svg",'$& xmlns="http://www.w3.org/2000/svg" style="height: 1em; width: 1em; display: inline-block; transform: translateY(0.1em);"')}},template:'<span v-html="svgCode"></span>'}}function getJSValueComponentProps(){return{props:["description","path","name","isDimName","keyPath"],data:()=>({isExpanded:!1,hasBeenExpanded:!1}),watch:{isExpanded(e){e&&!this.hasBeenExpanded&&(this.hasBeenExpanded=e)},isPartialDescription(e){e&&this.isExpanded&&this.requestDescription()}},computed:{isPartialDescription(){return void 0===this.description.entries},isExpandable(){return!this.description.isPrimitive},isEntry(){return null!=this.name},classNames(){return["js-value",this.isEntry||this.isExpandable&&this.isExpanded?"d-block":"d-inline-block",this.isExpanded?"expanded":""]},entryGroups(){const{keyPath:e,description:t}=this;return[{key:"entries",isDim:e=>!1===e[2],getKeyPath:i=>e&&t.entriesArePropertyKeys?e.concat([i[0]]):null},{key:"protoEntries",isDim:()=>!0,getKeyPath:()=>e}]}},methods:{toggleExpanded(){this.isExpandable&&(this.isExpanded=!this.isExpanded,this.isExpanded&&this.isPartialDescription&&this.requestDescription())},requestDescription(){messageParent({target:"runner",func:"sendDescriptionFor",args:[this.path]})},openMenu(e){this.$root.openValueMenu(e,{path:this.path,keyPath:this.keyPath,isPrimitive:this.description.isPrimitive})}},template:'\n <div :class="classNames">\n <div :class="[\'js-value-header\', isExpandable ? \'expandable\' : \'\']" @click="toggleExpanded" @contextmenu.prevent.stop="openMenu"><span\n v-if="isExpandable || isEntry" :class="[\'arrow\', isExpandable ? \'expandable\' : \'\', isExpanded ? \'expanded\' : \'\']"></span><template\n v-if="isEntry"><span :class="[\'entry-key\', isDimName ? \'dim\' : \'\']">{{ name }}</span>: </template><span\n v-for="part in description.parts" :class="\'t-\' + part[0]">{{ part[1] }}</span></div>\n <div v-if="hasBeenExpanded" v-show="isExpanded" class="expansion">\n <div v-if="isPartialDescription" class="loading">Loading&hellip;</div>\n <template v-else>\n <template v-for="group in entryGroups">\n <js-value\n v-for="(entry, entryIndex) in description[group.key]"\n :name="entry[0]"\n :is-dim-name="group.isDim(entry)"\n :description="entry[1]"\n :key-path="group.getKeyPath(entry)"\n :path="path.concat([group.key, entryIndex])">\n </js-value>\n </template>\n </template>\n </div>\n </div>\n '}}function parseJSCodeGroups(e){return e.split(/\r\n|\r|\n/).reduce(((e,t)=>{const i=e[e.length-1],s=/^\/\/[^]*\\\\$/.test(t),o=s?t.replace(/^\/+\s*|\s*\\+$/g,""):t;return!e.length||s&&!i.canAppendHeader?e.push({headerLines:s?[o]:[],lines:s?[]:[t],allLines:[t],canAppendHeader:s}):s?(i.headerLines.push(o),i.allLines.push(t)):(i.canAppendHeader=!1,i.lines.push(t),i.allLines.push(t)),e}),[]).reduce(((e,t)=>(t.canAppendHeader||(delete t.canAppendHeader,t.headerLines=t.headerLines.join("\n").trimEnd(),t.lines=t.lines.join("\n"),t.allLines=t.allLines.join("\n"),e.push(t)),e)),[])}function parseGroupHeader(e,t){const i=!!t&&e.startsWith(t);return{header:i?e.slice(t.length).replace(/^\s*:?\s*/,""):e,isHidden:i}}function extractHiddenGroups(e,t){const i=[],s=[];for(const o of parseJSCodeGroups(e))parseGroupHeader(o.headerLines,t).isHidden?s.push({...o,runCount:i.length}):i.push(o);return{visibleCode:i.map((e=>e.allLines)).join("\n"),hiddenGroups:s}}function compileTypeScript(e,{blockType:t}){try{const i=Babel.transform(e,{filename:"snippet.ts",presets:[["typescript",{allExtensions:!0,onlyRemoveTypeImports:!0}]],sourceType:"module"===t?"module":"script",parserOpts:{allowImportExportEverywhere:"module"!==t},retainLines:!0,sourceMaps:!0});return{code:i.code,sourceMap:decodeSourceMap(i.map.mappings)}}catch(t){if("SyntaxError"!==t?.name||!t.loc)throw t;return{code:e,error:{message:`${t.message}`.split("\n")[0].replace(/^\/?snippet\.ts:\s*/,"").replace(/\s*\(\d+:\d+\)$/,""),line:t.loc.line,column:t.loc.column+1}}}}function decodeSourceMap(e){const t=[0,0,0,0,0];return e.split(";").map((e=>{t[0]=0;const i=[];for(const s of e.split(",")){if(!s)continue;const e=[];let o=0,r=0;for(const t of s){const i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(t);o+=(31&i)<<r,32&i?r+=5:(e.push(1&o?-(o>>>1):o>>>1),o=r=0)}e.forEach(((e,i)=>t[i]+=e)),e.length>=4&&i.push([t[0],t[2],t[3]])}return i.sort(((e,t)=>e[0]-t[0]))}))}function prepareCode(e,{blockType:t,importsUrl:i,findResult:s}){if(!window.acorn)return{code:e,resultRange:null};let o;try{o=acorn.parse(e,{ecmaVersion:"latest",sourceType:"module"===t?"module":"script",allowHashBang:!0})}catch(t){return{code:e,resultRange:null}}let r=null;if(s){const e=o.body[o.body.length-1];"ExpressionStatement"!==e?.type||e.directive||(r=[e.expression.start,e.expression.end])}const n=[];i&&walkAst(o,(e=>{const{source:t}=/^(Import(Declaration|Expression)|Export(All|Named)Declaration)$/.test(e.type)?e:{};"Literal"===t?.type&&"string"==typeof t.value&&isBareSpecifier(t.value)&&n.push({start:t.start,end:t.end,text:JSON.stringify(i.replace(/\{specifier\}/g,t.value))})})),n.sort(((e,t)=>t.start-e.start));for(const{start:t,end:i,text:s}of n){e=e.slice(0,t)+s+e.slice(i);const o=s.length-(i-t);r&&(r=r.map((e=>e>=i?e+o:e)))}return{code:e,resultRange:r}}function formatPropertyPath(e){return e.map(((e,t)=>/^(0|[1-9]\d*)$/.test(e)?`[${e}]`:/^[A-Za-z_$][\w$]*$/.test(e)?(t?".":"")+e:`[${JSON.stringify(e)}]`)).join("")}function isBareSpecifier(e){return!/^(\.{0,2}\/|#|[a-z][a-z\d+.-]*:)/i.test(e)}function walkAst(e,t){if(Array.isArray(e))for(const i of e)walkAst(i,t);else if(e&&"string"==typeof e.type){t(e);for(const i of Object.keys(e)){const s=e[i];s&&"object"==typeof s&&walkAst(s,t)}}}function joinCodeBlocks(e){return e.map((e=>e.replace(/^(\s*[\r\n])+|\s+$/g,""))).filter(Boolean).map(((e,t)=>{const i=e.split(/\r\n|\r|\n/)[0];return t&&!/^\/\/[^]*\\\\$/.test(i)?`// \\\\\n${e}`:e})).join("\n\n")}function buildConsoleHtml({code:e,dataset:t,packageInfo:i,isFullPage:s}){const{name:o,version:r}=i,n=`https://cdn.jsdelivr.net/npm/${o}@${r.split(".")[0]}/dist/${o}.min.js`,a=Object.entries(t).map((([e,t])=>` data-${e.replace(/[A-Z]/g,(e=>"-"+e.toLowerCase()))}="${escapeHtmlAttribute(t)}"`)).join(""),l=s?" ":" ",c=e.replace(/<\/(script)/gi,"<\\/$1").replace(/<!--/g,"<\\!--"),d=(c.trim()?[`<script src="${n}"${a}>`,...c.split("\n").map((e=>e.trim()?" "+e:"")),"<\/script>"]:[`<script src="${n}"${a}><\/script>`]).map((e=>e?l+e:e)).join("\n");return s?["<!DOCTYPE html>",'<html lang="en">'," <head>",' <meta charset="utf-8">',' <meta name="viewport" content="width=device-width, initial-scale=1">'," <title>JS Box</title>"," <style>"," html, body { height: 100%; margin: 0; }"," </style>"," </head>"," <body>",d," </body>","</html>",""].join("\n"):`<div style="height: 400px;">\n${d}\n</div>\n`}function escapeHtmlAttribute(e){return`${e}`.replace(/[&"<>]/g,(e=>`&#${e.charCodeAt(0)};`))}function unindentMin(e,t){const i=(t=Object(t)).tabSize??4,s=t.trim??!0;if(e=e.replace(/\t/g," ".repeat(i)),!/(^|[\r\n])\S/.test(e)){const t=/(^|[\r\n])((?:(?!\r|\n)\s)+)(?=(\S)?)/g;let i=1/0;for(let s;s=t.exec(e);)s[3]&&(i=Math.min(i,s[2].length));e=e.replace(t,((e,t,s)=>t+s.slice(i)))}return s?e.replace(/^(\s*[\r\n]+)+|\s+$/g,""):e}function sanitizeDescription(e){return{typeName:`${(e=Object(e)).typeName}`,isPrimitive:!!e.isPrimitive,parts:Array.from(e.parts??[],(e=>[/^[a-z]+$/.test(Object(e)[0])?e[0]:"text",`${Object(e)[1]}`])),...sanitizeEntries(e),...null!=e.entriesArePropertyKeys?{entriesArePropertyKeys:!!e.entriesArePropertyKeys}:{}}}function sanitizeEntries(e){e=Object(e);const t={};for(const i of["entries","protoEntries"])Array.isArray(e[i])&&(t[i]=e[i].map((e=>[`${Object(e)[0]}`,sanitizeDescription(Object(e)[1]),!1!==Object(e)[2]])));return t}function appendLog({logId:e,key:t,descriptions:i,table:s,groupIds:o,groupId:r,isCollapsed:n,stack:a}){t=`${t}`,mountedApp.displays.push({type:"log",key:t,name:"result"===t?"Result":`console.${t}`,descriptions:Array.from(i,sanitizeDescription),table:s?{headers:Array.from(s.headers,(e=>`${e}`)),rows:Array.from(s.rows,(e=>({index:`${e.index}`,cells:Array.from(e.cells,(e=>e&&sanitizeDescription(e)))})))}:null,groupIds:Array.from(o??[],(e=>`${e}`)),groupId:null!=r?`${r}`:null,isCollapsed:!!n,stack:null!=a?`${a}`:null,logId:`${e}`})}function appendError({message:e,line:t,column:i}){mountedApp.displays.push({type:"error",message:`${e}`,line:+t,column:+i})}function updateDescriptionFor(e,t){const i=(e=Array.from(e)).shift(),s=mountedApp.displays.find((e=>"log"===e.type&&e.logId===i));let o=s?.descriptions[toIndex(e.shift())];for(let t=0;o&&t<e.length;t+=2){const i=e[t];if("entries"!==i&&"protoEntries"!==i)return;o=o[i]?.[toIndex(e[t+1])]?.[1]}if(o&&(Object.assign(o,sanitizeEntries(t)),o.entriesArePropertyKeys=!!Object(t).entriesArePropertyKeys,Array.isArray(Object(t).parts))){const{typeName:e,isPrimitive:i,parts:s}=sanitizeDescription(t);Object.assign(o,{typeName:e,isPrimitive:i,parts:s})}}function onValueJson(e){const{requestId:t,json:i,circularCount:s,error:o}=Object(e),r=jsonRequests.get(`${t}`);r&&(jsonRequests.delete(`${t}`),r({json:null!=i?`${i}`:null,circularCount:+s||0,error:null!=o?`${o}`:null}))}const jsonRequests=new Map;function onStoredAsGlobal(e){mountedApp.displays.push({type:"notice",message:`Stored as the global variable ${e}`})}function onCodeRan(){mountedApp.runningCount=Math.max(0,mountedApp.runningCount-1),mountedApp.runHiddenGroups()}function setPoppedOut(e,t){mountedApp.isPoppedOut=e,t&&mountedApp.restoreState(t)}function popIn(){mountedApp.bringBack()}function onPopOutFailed(){mountedApp.displays.push({type:"notice",message:"The pop-out window was blocked by the browser. Allow pop-ups for this site and try again."})}function clearDisplays(){mountedApp.displays=[{type:"notice",message:"Console was cleared"}]}function toIndex(e){return Number.isInteger(e)&&e>=0?e:void 0}
361
361
  },
@@ -417,6 +417,37 @@
417
417
  insert(inlineViewer.iframe);
418
418
 
419
419
  let isDestroyed = false;
420
+
421
+ /**
422
+ * Loads the viewer and starts the runner (which, in window mode, is when
423
+ * the page's console functions start being captured).
424
+ */
425
+ function load() {
426
+ if (runner || isDestroyed) return;
427
+ runner = runnerMode === 'window'
428
+ ? createWindowRunner(sendToViewer)
429
+ : createWorkerRunner(sendToViewer);
430
+ inlineViewer.load();
431
+ }
432
+
433
+ // Unless data-loading="eager" is given, nothing is loaded until the console
434
+ // is about to be scrolled into view (or a hidden console is shown).
435
+ /** @type {IntersectionObserver?} */
436
+ let loadObserver = null;
437
+ if (dataset.loading !== 'eager' && 'function' === typeof window.IntersectionObserver) {
438
+ loadObserver = new IntersectionObserver(entries => {
439
+ if (entries.some(entry => entry.isIntersecting)) {
440
+ loadObserver.disconnect();
441
+ loadObserver = null;
442
+ load();
443
+ }
444
+ }, {rootMargin: '200px'});
445
+ loadObserver.observe(inlineViewer.iframe);
446
+ }
447
+ else {
448
+ load();
449
+ }
450
+
420
451
  return {
421
452
  element: inlineViewer.iframe,
422
453
  /**
@@ -432,7 +463,8 @@
432
463
  popOutWindow = null;
433
464
  }
434
465
  removeEventListener('pagehide', closePopOut);
435
- runner.destroy();
466
+ loadObserver?.disconnect();
467
+ runner?.destroy();
436
468
  inlineViewer.dispose();
437
469
  inlineViewer.iframe.remove();
438
470
  },
@@ -468,7 +500,7 @@
468
500
  * The options of YourJSBox.create() which are the same as the data
469
501
  * attributes of a script tag.
470
502
  */
471
- const CONSOLE_OPTION_NAMES = ['blockType', 'dividerOrient', 'hidePrefix', 'importsUrl', 'language', 'librariesUrl', 'runner', 'showResults', 'theme'];
503
+ const CONSOLE_OPTION_NAMES = ['blockType', 'dividerOrient', 'hidePrefix', 'importsUrl', 'language', 'librariesUrl', 'loading', 'runner', 'showResults', 'theme'];
472
504
 
473
505
  /**
474
506
  * The JavaScript API for creating consoles (available as window.YourJSBox).
@@ -501,6 +533,7 @@
501
533
  * @param {string=} options.theme
502
534
  * @param {string=} options.librariesUrl
503
535
  * @param {string=} options.importsUrl
536
+ * @param {string=} options.loading
504
537
  * The same as the data attributes of a script tag.
505
538
  * @returns {{element: HTMLIFrameElement, destroy: () => void}}
506
539
  */
@@ -585,6 +618,8 @@
585
618
  * @param {Window=} options.targetWindow
586
619
  * If given the page is written into this (same origin) window (eg. a
587
620
  * pop-out window) instead of into a new IFRAME.
621
+ * @param {boolean=} options.deferLoad
622
+ * If true the IFRAME's page isn't loaded until `load()` is called.
588
623
  * @param {((this: R, event: MessageEvent) => void)=} options.onMessage
589
624
  * @param {((this: R, event: MessageEvent) => void)=} options.onReady
590
625
  * @returns {R}
@@ -666,9 +701,9 @@
666
701
  TARGET_WINDOW.document.close();
667
702
  }
668
703
  else {
669
- IFRAME.srcdoc = HTML_CODE;
670
704
  // Allows the console to go full screen.
671
705
  IFRAME.setAttribute('allow', 'fullscreen');
706
+ if (!options.deferLoad) IFRAME.srcdoc = HTML_CODE;
672
707
  }
673
708
 
674
709
  // Set the style of the iframe.
@@ -730,6 +765,10 @@
730
765
  },
731
766
  iframe: IFRAME,
732
767
  window: TARGET_WINDOW,
768
+ // Loads the IFRAME's page if it was deferred.
769
+ load: function() {
770
+ if (IFRAME && !IFRAME.srcdoc) IFRAME.srcdoc = HTML_CODE;
771
+ },
733
772
  // Stops listening for messages from the frame.
734
773
  dispose: function() {
735
774
  removeEventListener('message', onWindowMessage);
@@ -743,6 +782,7 @@
743
782
  * @property {(funcName: string, ...args: any[]) => void} call
744
783
  * @property {HTMLIFrameElement?} iframe
745
784
  * @property {Window=} window
785
+ * @property {() => void} load
746
786
  * @property {() => void} dispose
747
787
  */
748
788
 
@@ -1,9 +1,9 @@
1
- /*! yourjs-box v1.7.0 | (c) 2023-present Chris West | MIT License | https://github.com/westc/yourjs-box */
2
- (()=>{const VIEWER_IFRAME_CSS="[v-cloak]{display:none}body,html{height:100%;margin:0}body{background-color:var(--console-bg);font-family:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif}#vueApp{display:flex;flex-direction:column;inset:0;position:fixed}#main{display:grid;flex-grow:1;gap:0;min-height:0;position:relative}#main.is-moving-divider{-webkit-user-select:none;user-select:none}#main.col-orient.is-moving-divider{cursor:col-resize}#main.row-orient.is-moving-divider{cursor:row-resize}#main.is-moving-divider::after{background-color:var(--accent);content:'';position:absolute;z-index:99}#main.col-orient.is-moving-divider::after{bottom:0;left:calc(100% - var(--temp-editor-pct) - var(--divider-size)/ 2 - 1px);top:0;width:2px}#main.row-orient.is-moving-divider::after{height:2px;left:0;right:0;top:calc(100% - var(--temp-editor-pct) - var(--divider-size)/ 2 - 1px)}#main.col-orient{grid-template-columns:1fr var(--divider-size) calc(var(--editor-pct) - var(--divider-size)/ 2);grid-template-rows:1fr}#main.row-orient{grid-template-columns:1fr;grid-template-rows:1fr var(--divider-size) calc(var(--editor-pct) - var(--divider-size)/ 2)}.divider{background-color:var(--divider-bg);box-sizing:border-box;position:relative;transition:background-color .15s}#main.col-orient .divider{border-left:1px solid var(--toolbar-border);border-right:1px solid var(--toolbar-border);cursor:col-resize}#main.row-orient .divider{border-bottom:1px solid var(--toolbar-border);border-top:1px solid var(--toolbar-border);cursor:row-resize}.divider::after{background-color:var(--divider-grip);border-radius:2px;content:'';left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);transition:background-color .15s}#main.col-orient .divider::after{height:32px;width:2px}#main.row-orient .divider::after{height:2px;width:32px}#main.is-moving-divider .divider,.divider:hover{background-color:var(--divider-hover-bg)}#main.is-moving-divider .divider::after,.divider:hover::after{background-color:var(--accent)}#displays{position:relative}#displays>div{position:absolute;inset:0;overflow:auto}#bottomNav{align-items:center;background-color:var(--toolbar-bg);border-top:1px solid var(--toolbar-border);color:var(--toolbar-text);display:flex;flex:0 0 auto;font-size:12px;gap:8px;height:32px;padding:0 6px 0 8px;-webkit-user-select:none;user-select:none}#bottomNav>.brand{align-items:center;display:flex;flex-grow:1;gap:8px}.runner-badge{border:1px solid var(--toolbar-border);border-radius:999px;color:var(--muted-text);font-size:10px;letter-spacing:.04em;line-height:15px;padding:0 6px;text-transform:uppercase}#bottomNav>.buttons{align-items:center;display:flex;gap:2px}#bottomNav .separator{background-color:var(--toolbar-border);height:16px;margin:0 4px;width:1px}#bottomNav button{align-items:center;background:0 0;border:0;border-radius:4px;color:inherit;cursor:pointer;display:inline-flex;font:inherit;gap:5px;height:24px;justify-content:center;min-width:26px;padding:0 6px}#bottomNav button>span:not(.label){display:inline-flex;font-size:14px}#bottomNav button svg:not(.spin){transform:none!important}#bottomNav button:hover:not(:disabled){background-color:var(--button-hover)}#bottomNav button:disabled{cursor:not-allowed;opacity:.45}#bottomNav button.primary{background-color:var(--accent);color:var(--accent-text);font-weight:600;margin-left:2px;padding:0 10px 0 8px}#bottomNav button.primary>span:not(.label){font-size:11px}#bottomNav button.primary:hover:not(:disabled){background-color:var(--accent-hover)}#bottomNav button:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.spin{animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.logo{align-items:center;color:var(--toolbar-text);display:inline-flex;font-weight:700;gap:5px;letter-spacing:-.01em;line-height:1}.logo-mark{align-items:flex-end;background-color:#f7df1e;border-radius:3px;box-sizing:border-box;color:#1a1a1a;display:inline-flex;font-size:9.5px;font-weight:800;height:18px;justify-content:flex-end;letter-spacing:-.02em;padding:0 2px 2px 0;width:18px}.logo-text{font-size:14px}.logo-large{gap:12px}.logo-large>.logo-mark{border-radius:10px;box-shadow:0 8px 24px rgb(0 0 0 / .18);font-size:24px;height:56px;padding:0 6px 5px 0;width:56px}.logo-large>.logo-text{font-size:36px}#splash{align-items:center;background-color:var(--console-bg);display:flex;inset:0;justify-content:center;position:fixed;transition:opacity .35s ease,visibility .35s;z-index:1000}#splash.hidden{opacity:0;visibility:hidden}.splash-content{align-items:center;animation:splash-in .4s ease-out both;display:flex;flex-direction:column;gap:24px}.splash-progress{background-color:var(--toolbar-border);border-radius:3px;height:3px;overflow:hidden;width:140px}.splash-progress>div{animation:splash-progress 1.1s ease-in-out infinite;background-color:var(--accent);border-radius:inherit;height:100%;width:40%}@keyframes splash-in{from{opacity:0;transform:translateY(6px)}}@keyframes splash-progress{from{transform:translateX(-100%)}to{transform:translateX(250%)}}.dialog-backdrop{align-items:center;animation:fade-in .12s ease-out;background-color:var(--backdrop);display:flex;inset:0;justify-content:center;position:fixed;z-index:900}.dialog{animation:dialog-in .15s ease-out;background-color:var(--dialog-bg);border:1px solid var(--toolbar-border);border-radius:8px;box-shadow:0 12px 40px rgb(0 0 0 / .3);color:var(--console-text);font-size:13px;padding:16px;width:min(360px,calc(100% - 32px))}.dialog-title{font-size:14px;font-weight:600;margin-bottom:6px}.dialog-message{color:var(--muted-text);line-height:1.45}.dialog-buttons{display:flex;gap:8px;justify-content:flex-end;margin-top:16px}.dialog-button{background:0 0;border:1px solid var(--toolbar-border);border-radius:4px;color:inherit;cursor:pointer;font:inherit;height:28px;padding:0 12px}.dialog-button:hover{background-color:var(--button-hover)}.dialog-button.primary{background-color:var(--accent);border-color:var(--accent);color:var(--accent-text);font-weight:600}.dialog-button.primary:hover{background-color:var(--accent-hover)}.dialog-button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}#bottomNav button.logo-button{margin-left:-4px;padding:0 4px}.about-dialog{display:flex;flex-direction:column;max-height:calc(100% - 24px);padding:0;width:min(620px,calc(100% - 24px))}.about-dialog.is-export{height:min(560px,calc(100% - 24px))}.about-header{align-items:center;border-bottom:1px solid var(--toolbar-border);display:flex;flex:0 0 auto;padding:0 8px 0 12px}.tabs{display:flex;flex-grow:1;gap:4px}.tab{background:0 0;border:0;border-bottom:2px solid transparent;color:var(--muted-text);cursor:pointer;font:inherit;font-weight:600;padding:10px 8px 8px}.tab:hover{color:var(--console-text)}.tab.active{border-bottom-color:var(--accent);color:var(--console-text)}.close-button{align-items:center;background:0 0;border:0;border-radius:4px;color:var(--muted-text);cursor:pointer;display:inline-flex;font-size:16px;height:28px;justify-content:center;width:28px}.close-button:hover{background-color:var(--button-hover);color:var(--console-text)}.close-button:focus-visible,.segmented>button:focus-visible,.tab:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}.about-body{flex:1 1 auto;min-height:0;overflow:auto;padding:16px}.about-title{align-items:center;display:flex;gap:12px}.logo-medium>.logo-mark{border-radius:7px;font-size:16px;height:40px;padding:0 4px 4px 0;width:40px}.logo-medium>.logo-text{display:none}.about-name{font-size:17px;font-weight:700}.about-aka{color:var(--muted-text);font-size:13px;font-weight:400;margin-left:4px}.about-version{color:var(--muted-text);font-size:12px}.about-description{line-height:1.5;margin:12px 0}.about-links{display:flex;flex-wrap:wrap;gap:6px 16px}.about-links a{color:var(--accent);font-weight:600;text-decoration:none}.about-links a:hover{text-decoration:underline}.about-body h3{color:var(--muted-text);font-size:11px;letter-spacing:.05em;margin:18px 0 6px;text-transform:uppercase}.about-details{display:grid;gap:4px 16px;grid-template-columns:max-content 1fr;margin:0}.about-details dt{color:var(--muted-text)}.about-details dd{margin:0}.about-details kbd{background-color:var(--toolbar-bg);border:1px solid var(--toolbar-border);border-bottom-width:2px;border-radius:4px;font-family:inherit;font-size:11px;padding:0 4px}.about-footer{border-top:1px solid var(--toolbar-border);color:var(--muted-text);font-size:12px;margin-top:18px;padding-top:12px}.export-body{display:flex;flex-direction:column;gap:10px}.export-options{display:flex;flex-wrap:wrap;gap:8px;justify-content:space-between}.segmented{border:1px solid var(--toolbar-border);border-radius:6px;display:inline-flex;overflow:hidden}.segmented>button{background:0 0;border:0;color:var(--muted-text);cursor:pointer;font:inherit;font-size:12px;font-weight:600;padding:5px 10px}.segmented>button+button{border-left:1px solid var(--toolbar-border)}.segmented>button:hover{background-color:var(--button-hover)}.segmented>button.active{background-color:var(--accent);color:var(--accent-text)}.export-note{color:var(--muted-text);font-size:12px}.export-preview{border:1px solid var(--toolbar-border);border-radius:6px;flex:1 1 auto;min-height:120px;overflow:hidden}.export-actions{display:flex;gap:8px;justify-content:flex-end}.file-input{display:none}.more-menu{background-color:var(--dialog-bg);border:1px solid var(--toolbar-border);border-radius:8px;bottom:38px;box-shadow:0 8px 28px rgb(0 0 0 / .25);color:var(--console-text);font-size:13px;max-height:calc(100% - 48px);min-width:236px;overflow:auto;padding:4px;position:absolute;right:6px;z-index:800}.menu-item{align-items:center;background:0 0;border:0;border-radius:5px;color:inherit;cursor:pointer;display:flex;font:inherit;gap:8px;padding:6px 8px;text-align:left;width:100%}.menu-item:focus-visible,.menu-item:hover:not(:disabled){background-color:var(--button-hover);outline:0}.menu-item:disabled{cursor:not-allowed;opacity:.4}.menu-icon{color:var(--muted-text);display:inline-flex;font-size:14px;justify-content:center;width:16px}.menu-icon svg{transform:none!important}.menu-row{align-items:center;display:flex;gap:2px;padding:2px 2px 2px 8px}.menu-row-label{flex-grow:1}.menu-step{font-weight:600;justify-content:center;width:auto}.menu-percent{color:var(--muted-text);font-variant-numeric:tabular-nums;font-weight:400;min-width:52px}.menu-separator{background-color:var(--toolbar-border);height:1px;margin:4px 0}.history-panel{max-width:min(420px,calc(100% - 12px));width:360px}.history-title{color:var(--muted-text);font-size:11px;font-weight:600;letter-spacing:.05em;padding:4px 8px 6px;text-transform:uppercase}.history-item{justify-content:space-between}.history-label{font-family:var(--console-font);font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.history-detail{color:var(--muted-text);flex-shrink:0;font-size:11px}.history-empty,.history-hint{color:var(--muted-text);font-size:12px;padding:6px 8px}.history-hint{border-top:1px solid var(--toolbar-border);margin-top:4px}.value-menu{bottom:auto;min-width:220px;position:fixed;right:auto;z-index:850}.toast{animation:fade-in .15s ease-out;background-color:var(--console-text);border-radius:6px;bottom:44px;box-shadow:0 6px 20px rgb(0 0 0 / .25);color:var(--console-bg);font-size:12px;left:50%;max-width:calc(100% - 32px);padding:6px 12px;pointer-events:none;position:fixed;transform:translateX(-50%);z-index:860}.popped-out{align-items:center;background-color:var(--console-bg);color:var(--console-text);display:flex;inset:0;justify-content:center;position:fixed;z-index:950}.popped-out-content{align-items:center;display:flex;flex-direction:column;gap:8px;padding:16px;text-align:center}.popped-out-title{font-size:15px;font-weight:600;margin-top:8px}.popped-out-text{color:var(--muted-text);font-size:13px}@keyframes fade-in{from{opacity:0}}@keyframes dialog-in{from{opacity:0;transform:scale(.96)}}.rotated-90deg{transform:rotate(90deg)}.align-top{vertical-align:top!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.no-select{-webkit-user-select:none;user-select:none}:root{color-scheme:light;--console-font:ui-monospace,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;--console-bg:#fff;--console-text:#1f1f1f;--row-border:#f0f0f0;--arrow:#727272;--chevron:#9aa0a6;--entry-key:#881391;--preview-key:#5f6368;--string:#c41a16;--number:#1a1aa6;--null:#80868b;--header-bg:#f1f3f4;--header-text:#3c4043;--warn-bg:#fffbe5;--warn-border:#fff5c2;--warn-text:#5c3c00;--warn-icon:#e8a600;--error-bg:#fff0f0;--error-border:#ffd6d6;--error-text:#dc362e;--error-icon:#dc362e;--table-header-bg:#f3f3f3;--table-border:#d0d0d0;--toolbar-bg:#f3f3f3;--toolbar-border:#d6d6d6;--toolbar-text:#333;--muted-text:#5f6368;--button-hover:rgb(0 0 0 / 0.08);--accent:#1a73e8;--accent-hover:#1765cc;--accent-text:#fff;--divider-bg:#f3f3f3;--divider-hover-bg:#e8eaed;--divider-grip:#b0b0b0;--dialog-bg:#fff;--backdrop:rgb(0 0 0 / 0.25)}:root[data-theme=dark]{color-scheme:dark;--console-bg:#242424;--console-text:#e3e3e3;--row-border:#3a3a3a;--arrow:#9aa0a6;--chevron:#80868b;--entry-key:#5db0d7;--preview-key:#9aa0a6;--string:#f28b54;--number:#9980ff;--null:#8e8e8e;--header-bg:#2d2e30;--header-text:#c4c7c5;--warn-bg:#332b00;--warn-border:#665500;--warn-text:#ffd17a;--warn-icon:#ffd17a;--error-bg:#290000;--error-border:#5c0000;--error-text:#ff8080;--error-icon:#ff6b6b;--table-header-bg:#2e2e2e;--table-border:#4a4a4a;--toolbar-bg:#2b2b2b;--toolbar-border:#474747;--toolbar-text:#e3e3e3;--muted-text:#9aa0a6;--button-hover:rgb(255 255 255 / 0.1);--accent:#8ab4f8;--accent-hover:#aecbfa;--accent-text:#202124;--divider-bg:#2b2b2b;--divider-hover-bg:#333;--divider-grip:#6b6b6b;--dialog-bg:#2d2e30;--backdrop:rgb(0 0 0 / 0.5)}#displays{background-color:var(--console-bg);color:var(--console-text)}#displays>div{font-family:var(--console-font);font-size:calc(12px * var(--text-scale, 1));line-height:calc(16px * var(--text-scale, 1))}.console-row{border-bottom:1px solid var(--row-border);padding:2px 8px 2px 24px;position:relative;white-space:pre-wrap;word-break:break-word}.console-row>.row-icon{left:6px;line-height:0;position:absolute;top:4px}.log-error,.log-warn{margin-top:-1px}.log-warn{background-color:var(--warn-bg);border-bottom-color:var(--warn-border);border-top:1px solid var(--warn-border);color:var(--warn-text)}.log-warn>.row-icon{color:var(--warn-icon)}.log-error{background-color:var(--error-bg);border-bottom-color:var(--error-border);border-top:1px solid var(--error-border);color:var(--error-text)}.log-error>.row-icon{color:var(--error-icon)}.console-row{padding-left:calc(24px + var(--depth,0) * 16px)}.console-row>.row-icon{left:calc(6px + var(--depth,0) * 16px)}.group-header{cursor:pointer;font-weight:700}.group-header>.row-icon.arrow{top:5px}.log-assert{background-color:var(--error-bg);border-bottom-color:var(--error-border);border-top:1px solid var(--error-border);color:var(--error-text);margin-top:-1px}.log-assert>.row-icon{color:var(--error-icon)}.log-result>.row-icon{color:var(--chevron)}.trace-stack{color:var(--null);padding-left:1ch}.splash-message{color:var(--muted-text);font-size:13px;max-width:280px;text-align:center}.splash-slow{animation:show-after-delay 0s 10s both}@keyframes show-after-delay{from{visibility:hidden}to{visibility:visible}}#splash.failed .splash-progress,#splash.failed .splash-slow,.splash-error{display:none}#splash.failed .splash-error{display:block}.code-header{background-color:var(--header-bg);border-bottom:1px solid var(--row-border);color:var(--header-text);font-weight:700;padding:2px 8px;white-space:pre-wrap}.code-header.toggleable{cursor:pointer}.code-row .copy-to-editor-button{align-items:center;background-color:var(--console-bg);border:1px solid var(--toolbar-border);border-radius:4px;color:var(--toolbar-text);cursor:pointer;display:inline-flex;height:22px;justify-content:center;opacity:0;padding:0;position:absolute;right:6px;top:2px;transition:opacity .15s;width:22px}.code-row .copy-to-editor-button:focus-visible,.code-row:hover .copy-to-editor-button{opacity:1}.code-row .copy-to-editor-button:hover{background-color:var(--toolbar-bg)}@media (hover:none){.code-row .copy-to-editor-button{opacity:.8}}.notice{color:var(--null);font-style:italic}.code-row>.row-icon{color:var(--chevron)}.code-row code,.code-row pre{background:0 0!important;font-family:var(--console-font)!important;font-size:calc(12px * var(--text-scale, 1))!important;line-height:calc(16px * var(--text-scale, 1))!important;padding:0!important;text-shadow:none!important}.js-value{max-width:100%;vertical-align:top}.row-content>.js-value+.js-value{margin-left:1ch}.js-value-header.expandable{cursor:default}.js-value .expansion{padding-left:12px}.js-value .loading{color:var(--null);padding-left:12px}.arrow{display:inline-block;height:10px;position:relative;width:12px}.arrow.expandable::before{border-color:transparent transparent transparent var(--arrow);border-style:solid;border-width:4px 0 4px 6px;content:'';left:2px;position:absolute;top:1px;transform-origin:3px 4px;transition:transform .1s}.arrow.expandable.expanded::before{transform:rotate(90deg)}.entry-key{color:var(--entry-key)}.entry-key.dim{opacity:.6}.t-key{color:var(--preview-key)}.t-regexp,.t-string,.t-symbol{color:var(--string)}.t-number{color:var(--number)}.t-null{color:var(--null)}.t-function{font-style:italic}.t-node{color:var(--entry-key)}.console-table{border:1px solid var(--table-border);border-collapse:collapse;margin:2px 0 4px;white-space:nowrap}.console-table td,.console-table th{border-left:1px solid var(--table-border);max-width:300px;overflow:hidden;padding:1px 4px;text-align:left;text-overflow:ellipsis}.console-table th{background-color:var(--table-header-bg);border-bottom:1px solid var(--table-border);font-weight:400}",PACKAGE_INFO={name:"yourjs-box",version:"1.7.0",homepage:"https://westc.github.io/yourjs-box/",repoUrl:"https://github.com/westc/yourjs-box",bugsUrl:"https://github.com/westc/yourjs-box/issues"},VIEWER_IFRAME_HTML='<div id="splash" aria-label="Loading"><div class="splash-content"><span class="logo logo-large"><span class="logo-mark">JS</span><span class="logo-text">Box</span></span><div class="splash-progress"><div></div></div><div class="splash-message splash-slow">Still loading&hellip;</div><div class="splash-message splash-error">JS Box couldn&rsquo;t load. Please check your connection and reload the page.</div></div></div><div id="vueApp" v-cloak><input type="file" ref="fileInput" class="file-input" accept=".js,.mjs,.cjs,.ts,.mts,.cts,.txt,text/javascript,text/plain" tabindex="-1" aria-hidden="true" @change="onFileChosen"><div id="main" ref="main" :class="mainElemClassNames" :style="mainElemStyles" @mousedown="onMainElemMouseDown"><div id="displays"><div ref="displaysScroller" @scroll="onDisplaysScroll"><template v-for="display in displays"><div v-if="display.type === \'prism\'"><div v-if="display.isHidden" class="code-header toggleable no-select" @click="display.isCodeShown = !display.isCodeShown" :title="display.isCodeShown ? \'Hide Code\' : \'Show Code\'"><span :class="[\'arrow\', \'expandable\', display.isCodeShown ? \'expanded\' : \'\']"></span>{{ display.header || \'Hidden code\' }}</div><div v-else-if="display.header" class="code-header">{{ display.header }}</div><div v-if="display.isCodeShown" class="console-row code-row"><span class="row-icon"><icon name="chevron"></icon></span><prism :language="language" :code="display.value" :is-dark="theme === \'dark\'" match-braces></prism><button class="copy-to-editor-button" title="Copy to editor" @click="copyToEditor(display.value)"><icon name="copyToEditor"></icon></button></div></div><div v-if="display.type === \'log\' &amp;&amp; !isInCollapsedGroup(display)" :class="[\'console-row\', \'log-\' + display.key, display.groupId ? \'group-header\' : \'\']" :style="{\'--depth\': display.groupIds.length}" :title="display.name" @click="onLogRowClick(display, $event)"><span v-if="display.key === \'error\' || display.key === \'assert\'" class="row-icon"><icon name="consoleError"></icon></span><span v-else-if="display.key === \'warn\'" class="row-icon"><icon name="consoleWarning"></icon></span><span v-else-if="display.key === \'result\'" class="row-icon"><icon name="result"></icon></span><span v-else-if="display.groupId" :class="[\'row-icon\', \'arrow\', \'expandable\', display.isCollapsed ? \'\' : \'expanded\']"></span><div class="row-content"><table v-if="display.table" class="console-table"><thead><tr><th v-for="header in display.table.headers">{{ header }}</th></tr></thead><tbody><tr v-for="row in display.table.rows"><td>{{ row.index }}</td><td v-for="cell in row.cells"><template v-if="cell"><span v-for="part in cell.parts" :class="\'t-\' + part[0]">{{ part[1] }}</span></template></td></tr></tbody></table><js-value v-for="(description, index) in display.descriptions" :description="description" :key-path="[]" :path="[display.logId, index]"></js-value><div v-if="display.stack" class="trace-stack">{{ display.stack }}</div></div></div><div v-if="display.type === \'notice\'" class="console-row notice">{{ display.message }}</div><div v-if="display.type === \'error\'" class="console-row log-error"><span class="row-icon"><icon name="consoleError"></icon></span><div class="row-content">{{ display.message }}</div></div></template></div></div><div class="divider" ref="mainDivider"></div><div id="editor"><ace-editor ref="editor" v-model="jsCode" :language="language" :theme="theme" :font-size="Math.round(12 * textScale)" @key-combo="onEditorKeyCombo" @history-key="onEditorHistoryKey" height="100%"></ace-editor></div></div><div id="bottomNav"><div class="brand"><button class="logo-button" title="About JS Box" @click="openAbout(\'about\')"><span class="logo"><span class="logo-mark">JS</span><span class="logo-text">Box</span></span></button> <span class="runner-badge" :title="runnerMode === \'window\' ? \'Code runs directly in this page\' : \'Code runs in a Web Worker (no DOM access)\'">{{ runnerMode === \'window\' ? \'Window\' : \'Worker\' }}</span></div><div class="buttons"><template v-for="bottomButton in bottomButtons"><span v-if="bottomButton.isSeparator" class="separator"></span> <button v-else :class="bottomButton.className" @click="bottomButton.callback.call(this, $event)" :title="bottomButton.title" :disabled="bottomButton.disableIf &amp;&amp; bottomButton.disableIf.call(this)"><icon :name="bottomButton.iconName"></icon><span v-if="bottomButton.label" class="label">{{ bottomButton.label }}</span></button></template></div></div><div v-if="isMenuOpen" class="more-menu" role="menu" aria-label="More" ref="moreMenu" @keydown="onMenuKeyDown"><div class="menu-row" role="group" aria-label="Text size"><span class="menu-row-label">Text size</span> <button class="menu-item menu-step" role="menuitem" title="Smaller text" aria-label="Smaller text" :disabled="!canShrinkText" @click="changeTextScale(-1)">A&minus;</button> <button class="menu-item menu-step menu-percent" role="menuitem" title="Reset the text size" aria-label="Reset the text size" @click="setTextScale(1)">{{ Math.round(textScale * 100) }}%</button> <button class="menu-item menu-step" role="menuitem" title="Bigger text" aria-label="Bigger text" :disabled="!canGrowText" @click="changeTextScale(1)">A+</button></div><div class="menu-separator"></div><button class="menu-item" role="menuitem" @click="openFile()"><span class="menu-icon"><icon name="open"></icon></span>Open&hellip;</button> <button class="menu-item" role="menuitem" @click="saveFile()"><span class="menu-icon"><icon name="save"></icon></span>Save&hellip;</button><div class="menu-separator"></div><button v-if="isPopOut" class="menu-item" role="menuitem" @click="closeMenu(); bringBack()"><span class="menu-icon"><icon name="popIn"></icon></span>Bring back into the page</button> <button v-else class="menu-item" role="menuitem" @click="popOut()"><span class="menu-icon"><icon name="popOut"></icon></span>Pop out into a window</button> <button class="menu-item" role="menuitem" @click="closeMenu(); openAbout(\'html\')"><span class="menu-icon"><icon name="code"></icon></span>Copy as HTML&hellip;</button> <button class="menu-item" role="menuitem" @click="closeMenu(); resetConsole()"><span class="menu-icon"><icon name="refresh"></icon></span>Reset&hellip;</button><div class="menu-separator"></div><button class="menu-item" role="menuitem" @click="closeMenu(); openAbout(\'about\')"><span class="menu-icon"><icon name="info"></icon></span>About JS Box</button></div><div v-if="isHistoryOpen" class="more-menu history-panel" role="menu" aria-label="History" ref="historyPanel" @keydown="onMenuKeyDown"><div class="history-title">History</div><div v-if="!historyEntries.length" class="history-empty">Code that you run will show up here.</div><button v-for="entry in historyEntries" class="menu-item history-item" role="menuitem" :title="commandHistory[entry.index]" @click="recallHistory(entry.index)"><span class="history-label">{{ entry.label }}</span> <span class="history-detail">{{ entry.detail }}</span></button><div class="history-hint">Tip: press &uarr; at the start of the editor (or &darr; at the end) to go through the history.</div></div><div v-if="valueMenu" class="more-menu value-menu" role="menu" aria-label="Value" ref="valueMenu" :style="{left: valueMenu.x + \'px\', top: valueMenu.y + \'px\'}" @keydown="onMenuKeyDown"><button class="menu-item" role="menuitem" @click="copyValueAsJson()"><span class="menu-icon"><icon name="copy"></icon></span>Copy as JSON</button> <button class="menu-item" role="menuitem" @click="saveValueAsJson()"><span class="menu-icon"><icon name="save"></icon></span>Save as JSON&hellip;</button> <button class="menu-item" role="menuitem" @click="storeValueAsGlobal()"><span class="menu-icon"><icon name="variable"></icon></span>Store as global variable</button> <button v-if="valueMenu.propertyPath" class="menu-item" role="menuitem" @click="copyPropertyPath()"><span class="menu-icon"><icon name="path"></icon></span>Copy property path</button><template v-if="!valueMenu.isPrimitive"><div class="menu-separator"></div><button class="menu-item" role="menuitem" @click="refreshValue()"><span class="menu-icon"><icon name="refresh"></icon></span>Refresh</button></template></div><div v-if="toast" class="toast" role="status">{{ toast.message }}</div><div v-if="isPoppedOut" class="popped-out"><div class="popped-out-content"><span class="logo logo-medium"><span class="logo-mark">JS</span><span class="logo-text">Box</span></span><div class="popped-out-title">This console is open in a separate window</div><div class="popped-out-text">Its code still runs in this page.</div><div class="dialog-buttons"><button class="dialog-button" @click="focusPopOut">Show the window</button> <button class="dialog-button primary" @click="requestPopIn">Bring it back</button></div></div></div><div v-if="isAboutOpen" class="dialog-backdrop" @mousedown.self="closeAbout" @keydown.esc="closeAbout"><div :class="[\'dialog\', \'about-dialog\', aboutTab === \'html\' ? \'is-export\' : \'\']" role="dialog" aria-modal="true" aria-label="About JS Box"><div class="about-header"><div class="tabs" role="tablist"><button role="tab" :aria-selected="aboutTab === \'about\'" :class="[\'tab\', aboutTab === \'about\' ? \'active\' : \'\']" @click="aboutTab = \'about\'">About</button> <button role="tab" :aria-selected="aboutTab === \'html\'" :class="[\'tab\', aboutTab === \'html\' ? \'active\' : \'\']" @click="aboutTab = \'html\'">Copy as HTML</button></div><button class="close-button" ref="aboutCloseButton" title="Close" @click="closeAbout"><icon name="close"></icon></button></div><div v-if="aboutTab === \'about\'" class="about-body"><div class="about-title"><span class="logo logo-medium"><span class="logo-mark">JS</span><span class="logo-text">Box</span></span><div><div class="about-name">YourJS Box <span class="about-aka">aka JS Box</span></div><div class="about-version">Version {{ packageInfo.version }}</div></div></div><p class="about-description">An interactive JavaScript console that can be embedded in any web page with a single script tag.</p><div class="about-links"><a :href="packageInfo.homepage" target="_blank" rel="noopener">Website</a> <a :href="packageInfo.repoUrl" target="_blank" rel="noopener">GitHub</a> <a :href="packageInfo.repoUrl + \'#readme\'" target="_blank" rel="noopener">Documentation</a> <a :href="packageInfo.bugsUrl" target="_blank" rel="noopener">Report an issue</a></div><h3>This console</h3><dl class="about-details"><dt>Code runs in</dt><dd>{{ runnerDescription }}</dd><dt>Theme</dt><dd>{{ themeDescription }}</dd><dt>Language</dt><dd>{{ isTypeScript ? \'TypeScript (types are removed by Babel, not checked)\' : \'JavaScript\' }}</dd><dt>Code blocks run as</dt><dd>{{ blockTypeDescription }}</dd><dt>Imports</dt><dd>{{ importsUrl ? \'Packages imported by name load from \' + importsUrl.replace(\'{specifier}\', \'\u2026\') : \'Only URLs and paths can be imported\' }}</dd><dt>Results</dt><dd>{{ showResults ? \'The value of the last expression is shown\' : \'Not shown\' }}</dd><dt>Layout</dt><dd>{{ layoutDescription }}</dd></dl><h3>Keyboard shortcuts</h3><dl class="about-details"><dt><kbd>{{ modKey }}</kbd> + <kbd>Enter</kbd></dt><dd>Run the next block of code</dd><dt><kbd>&uarr;</kbd> / <kbd>&darr;</kbd></dt><dd>Go through the code that was run (at the very start or end of the editor)</dd><dt><kbd>{{ modKey === \'Ctrl\' ? \'Alt\' : \'&#8997;\' }}</kbd> + <kbd>H</kbd></dt><dd>Show the history</dd><dt><kbd>Esc</kbd></dt><dd>Close this window, the menu or full screen</dd></dl><div class="about-footer">MIT License &copy; 2023-present Chris West &middot; Built with {{ builtWith }}</div></div><div v-else class="about-body export-body"><div class="export-options"><div class="segmented" role="radiogroup" aria-label="Code"><button v-for="option in exportCodeOptions" role="radio" :aria-checked="exportCode === option.value" :class="exportCode === option.value ? \'active\' : \'\'" @click="exportCode = option.value">{{ option.label }}</button></div><div class="segmented" role="radiogroup" aria-label="Format"><button v-for="option in exportFormatOptions" role="radio" :aria-checked="exportFormat === option.value" :class="exportFormat === option.value ? \'active\' : \'\'" @click="exportFormat = option.value">{{ option.label }}</button></div></div><div class="export-note">{{ exportNote }}</div><div class="export-preview"><ace-editor :model-value="exportHtml" language="html" :theme="theme" height="100%" :read-only="true"></ace-editor></div><div class="export-actions"><button class="dialog-button" @click="downloadExport">Download page</button> <button class="dialog-button primary" @click="copyExport">{{ copyLabel }}</button></div></div></div></div><div v-if="dialog" class="dialog-backdrop" @mousedown.self="closeDialog(false)" @keydown.esc="closeDialog(false)"><div class="dialog" role="alertdialog" aria-modal="true" :aria-label="dialog.title"><div class="dialog-title">{{ dialog.title }}</div><div class="dialog-message">{{ dialog.message }}</div><div class="dialog-buttons"><button class="dialog-button" @click="closeDialog(false)">Cancel</button> <button class="dialog-button primary" ref="dialogConfirmButton" @click="closeDialog(true)">{{ dialog.confirmText }}</button></div></div></div></div>',OWN_URL=document.currentScript?.src??"",ORIGINAL_CONSOLE=window[Symbol.for("yourjs-box.originalConsole")]??={...console},LIBRARY_VERSIONS={"@babel/standalone":"7.29.9","ace-builds":"1.44.0",acorn:"8.18.0","prism-themes":"1.9.0",prismjs:"1.30.0",vue:"3.5.43"},DEFAULT_LIBRARIES_URL="https://unpkg.com/{name}@{version}/";function getLibraryFileUrl(librariesUrl,name,path){var librariesUrl=librariesUrl.replace(/\{(name|version)\}/g,(_,key)=>"name"===key?name:LIBRARY_VERSIONS[name]).replace(/\/?$/,"/");return new URL(librariesUrl+path,document.baseURI).href}const DEFAULT_IMPORTS_URL="https://esm.sh/{specifier}";function resolveUrlTemplate(template){var index=template.indexOf("{"),prefix=index<0?template:template.slice(0,index);return new URL(prefix||"./",document.baseURI).href.replace(/\/$/,prefix.endsWith("/")||!prefix?"/":"")+(index<0?"":template.slice(index))}const RELAYABLE_FUNCS={viewer:["appendLog","appendError","clearDisplays","onCodeRan","onStoredAsGlobal","onValueJson","updateDescriptionFor"],runner:["clearLogs","getValueAsJson","refreshDescription","reset","runCode","sendDescriptionFor","storeAsGlobal"],host:["focusPopOut","popIn","popOut","requestPopIn","setMaximized"]};function relayMessage(data,targets){var{target,func,args}=Object(data),targets=targets[target];targets&&RELAYABLE_FUNCS[target].includes(func)&&Array.isArray(args)?targets.apply(func,args):ORIGINAL_CONSOLE.error("Unhandled message sent to main handler:",data)}function createRunner(e,t){const{mode:n}=t,r=t.ownUrl||("worker"===n?self.location.href:""),o={};let s=0,i=0,c=!0,a;const l={},u={},f={},p={};let d=[],g=0;const h="yourjs-box.result."+Math.random().toString(36).slice(2),m=(globalThis[Symbol.for(h)]=v,[]);for(const e of["assert","clear","count","countReset","debug","dir","dirxml","error","group","groupCollapsed","groupEnd","info","log","table","time","timeEnd","timeLog","trace","warn"]){const t=console[e];if("function"==typeof t){const n=function(...n){return y(e,n),t.apply(this,arguments)};console[e]=n,m.push({key:e,original:t,wrapper:n})}}function y(t,n){var r=n.length&&void 0!==n[0]?""+n[0]:"default";if("clear"===t)K(),d=[],e({target:"viewer",func:"clearDisplays",args:[!0]});else if("assert"===t){if(!n[0]){const e=n.slice(1);b("assert",e.length?"string"==typeof e[0]?["Assertion failed: "+e[0],...e.slice(1)]:["Assertion failed:",...e]:["Assertion failed: console.assert"])}}else if("count"===t)f[r]=(f[r]||0)+1,b("count",[r+": "+f[r]]);else if("countReset"===t)Object.hasOwn(f,r)?f[r]=0:b("warn",[`Count for '${r}' does not exist`]);else if("time"===t)Object.hasOwn(p,r)?b("warn",[`Timer '${r}' already exists`]):p[r]=performance.now();else if("timeLog"===t||"timeEnd"===t){if(!Object.hasOwn(p,r))return b("warn",[`Timer '${r}' does not exist`]);const e=performance.now()-p[r];"timeEnd"===t&&delete p[r],b(t,[r+`: ${+e.toFixed(3)} ms`,..."timeLog"===t?n.slice(1):[]])}else if("trace"===t){const e=w((new Error).stack??"").split("\n").slice(1).join("\n");b("trace",n.length?n:["console.trace"],{stack:e})}else if("group"===t||"groupCollapsed"===t){const e=""+ ++g;b(t,n.length?n:["console.group"],{groupId:e,isCollapsed:"groupCollapsed"===t}),d.push(e)}else if("groupEnd"===t)d.pop();else{const e="table"===t?A(n[0],n[1]):null;b(t,e?n.slice(0,1):n,{table:e})}}function b(t,n,r,i=0){var c=""+ ++s;o[c]=n.map(e=>({...C(e,i),value:e})),e({target:"viewer",func:"appendLog",args:[{logId:c,key:t,descriptions:o[c].map(S(["value"])),groupIds:d.slice(),...r}]})}function v(e){void 0!==e&&b("result",[e],{},"string"==typeof e?1:0)}function $(e){O(void 0!==e.error?e.error:e.message)}function x(e){O(e.reason,!0)}function j(){removeEventListener("error",$),removeEventListener("unhandledrejection",x),delete globalThis[Symbol.for(h)];for(var{key:e,original:t,wrapper:n}of m)console[e]===n&&(console[e]=t);K()}function O(t,n){var r="classic"===a&&"SyntaxError"===t?.name?/\bawait\b/.test(t.message)?"top-level await":/\bimport\b/.test(t.message)?"import statements":null:null,r=r?`
1
+ /*! yourjs-box v1.8.0 | (c) 2023-present Chris West | MIT License | https://github.com/westc/yourjs-box */
2
+ (()=>{const VIEWER_IFRAME_CSS="[v-cloak]{display:none}body,html{height:100%;margin:0}body{background-color:var(--console-bg);font-family:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif}#vueApp{display:flex;flex-direction:column;inset:0;position:fixed}#main{display:grid;flex-grow:1;gap:0;min-height:0;position:relative}#main.is-moving-divider{-webkit-user-select:none;user-select:none}#main.col-orient.is-moving-divider{cursor:col-resize}#main.row-orient.is-moving-divider{cursor:row-resize}#main.is-moving-divider::after{background-color:var(--accent);content:'';position:absolute;z-index:99}#main.col-orient.is-moving-divider::after{bottom:0;left:calc(100% - var(--temp-editor-pct) - var(--divider-size)/ 2 - 1px);top:0;width:2px}#main.row-orient.is-moving-divider::after{height:2px;left:0;right:0;top:calc(100% - var(--temp-editor-pct) - var(--divider-size)/ 2 - 1px)}#main.col-orient{grid-template-columns:1fr var(--divider-size) calc(var(--editor-pct) - var(--divider-size)/ 2);grid-template-rows:1fr}#main.row-orient{grid-template-columns:1fr;grid-template-rows:1fr var(--divider-size) calc(var(--editor-pct) - var(--divider-size)/ 2)}.divider{background-color:var(--divider-bg);box-sizing:border-box;position:relative;transition:background-color .15s}#main.col-orient .divider{border-left:1px solid var(--toolbar-border);border-right:1px solid var(--toolbar-border);cursor:col-resize}#main.row-orient .divider{border-bottom:1px solid var(--toolbar-border);border-top:1px solid var(--toolbar-border);cursor:row-resize}.divider::after{background-color:var(--divider-grip);border-radius:2px;content:'';left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);transition:background-color .15s}#main.col-orient .divider::after{height:32px;width:2px}#main.row-orient .divider::after{height:2px;width:32px}#main.is-moving-divider .divider,.divider:hover{background-color:var(--divider-hover-bg)}#main.is-moving-divider .divider::after,.divider:hover::after{background-color:var(--accent)}#displays{position:relative}#displays>div{position:absolute;inset:0;overflow:auto}#bottomNav{align-items:center;background-color:var(--toolbar-bg);border-top:1px solid var(--toolbar-border);color:var(--toolbar-text);display:flex;flex:0 0 auto;font-size:12px;gap:8px;height:32px;padding:0 6px 0 8px;-webkit-user-select:none;user-select:none}#bottomNav>.brand{align-items:center;display:flex;flex-grow:1;gap:8px}.runner-badge{border:1px solid var(--toolbar-border);border-radius:999px;color:var(--muted-text);font-size:10px;letter-spacing:.04em;line-height:15px;padding:0 6px;text-transform:uppercase}#bottomNav>.buttons{align-items:center;display:flex;gap:2px}#bottomNav .separator{background-color:var(--toolbar-border);height:16px;margin:0 4px;width:1px}#bottomNav button{align-items:center;background:0 0;border:0;border-radius:4px;color:inherit;cursor:pointer;display:inline-flex;font:inherit;gap:5px;height:24px;justify-content:center;min-width:26px;padding:0 6px}#bottomNav button>span:not(.label){display:inline-flex;font-size:14px}#bottomNav button svg:not(.spin){transform:none!important}#bottomNav button:hover:not(:disabled){background-color:var(--button-hover)}#bottomNav button:disabled{cursor:not-allowed;opacity:.45}#bottomNav button.primary{background-color:var(--accent);color:var(--accent-text);font-weight:600;margin-left:2px;padding:0 10px 0 8px}#bottomNav button.primary>span:not(.label){font-size:11px}#bottomNav button.primary:hover:not(:disabled){background-color:var(--accent-hover)}#bottomNav button:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.spin{animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.logo{align-items:center;color:var(--toolbar-text);display:inline-flex;font-weight:700;gap:5px;letter-spacing:-.01em;line-height:1}.logo-mark{align-items:flex-end;background-color:#f7df1e;border-radius:3px;box-sizing:border-box;color:#1a1a1a;display:inline-flex;font-size:9.5px;font-weight:800;height:18px;justify-content:flex-end;letter-spacing:-.02em;padding:0 2px 2px 0;width:18px}.logo-text{font-size:14px}.logo-large{gap:12px}.logo-large>.logo-mark{border-radius:10px;box-shadow:0 8px 24px rgb(0 0 0 / .18);font-size:24px;height:56px;padding:0 6px 5px 0;width:56px}.logo-large>.logo-text{font-size:36px}#splash{align-items:center;background-color:var(--console-bg);display:flex;inset:0;justify-content:center;position:fixed;transition:opacity .35s ease,visibility .35s;z-index:1000}#splash.hidden{opacity:0;visibility:hidden}.splash-content{align-items:center;animation:splash-in .4s ease-out both;display:flex;flex-direction:column;gap:24px}.splash-progress{background-color:var(--toolbar-border);border-radius:3px;height:3px;overflow:hidden;width:140px}.splash-progress>div{animation:splash-progress 1.1s ease-in-out infinite;background-color:var(--accent);border-radius:inherit;height:100%;width:40%}@keyframes splash-in{from{opacity:0;transform:translateY(6px)}}@keyframes splash-progress{from{transform:translateX(-100%)}to{transform:translateX(250%)}}.dialog-backdrop{align-items:center;animation:fade-in .12s ease-out;background-color:var(--backdrop);display:flex;inset:0;justify-content:center;position:fixed;z-index:900}.dialog{animation:dialog-in .15s ease-out;background-color:var(--dialog-bg);border:1px solid var(--toolbar-border);border-radius:8px;box-shadow:0 12px 40px rgb(0 0 0 / .3);color:var(--console-text);font-size:13px;padding:16px;width:min(360px,calc(100% - 32px))}.dialog-title{font-size:14px;font-weight:600;margin-bottom:6px}.dialog-message{color:var(--muted-text);line-height:1.45}.dialog-buttons{display:flex;gap:8px;justify-content:flex-end;margin-top:16px}.dialog-button{background:0 0;border:1px solid var(--toolbar-border);border-radius:4px;color:inherit;cursor:pointer;font:inherit;height:28px;padding:0 12px}.dialog-button:hover{background-color:var(--button-hover)}.dialog-button.primary{background-color:var(--accent);border-color:var(--accent);color:var(--accent-text);font-weight:600}.dialog-button.primary:hover{background-color:var(--accent-hover)}.dialog-button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}#bottomNav button.logo-button{margin-left:-4px;padding:0 4px}.about-dialog{display:flex;flex-direction:column;max-height:calc(100% - 24px);padding:0;width:min(620px,calc(100% - 24px))}.about-dialog.is-export{height:min(560px,calc(100% - 24px))}.about-header{align-items:center;border-bottom:1px solid var(--toolbar-border);display:flex;flex:0 0 auto;padding:0 8px 0 12px}.tabs{display:flex;flex-grow:1;gap:4px}.tab{background:0 0;border:0;border-bottom:2px solid transparent;color:var(--muted-text);cursor:pointer;font:inherit;font-weight:600;padding:10px 8px 8px}.tab:hover{color:var(--console-text)}.tab.active{border-bottom-color:var(--accent);color:var(--console-text)}.close-button{align-items:center;background:0 0;border:0;border-radius:4px;color:var(--muted-text);cursor:pointer;display:inline-flex;font-size:16px;height:28px;justify-content:center;width:28px}.close-button:hover{background-color:var(--button-hover);color:var(--console-text)}.close-button:focus-visible,.segmented>button:focus-visible,.tab:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}.about-body{flex:1 1 auto;min-height:0;overflow:auto;padding:16px}.about-title{align-items:center;display:flex;gap:12px}.logo-medium>.logo-mark{border-radius:7px;font-size:16px;height:40px;padding:0 4px 4px 0;width:40px}.logo-medium>.logo-text{display:none}.about-name{font-size:17px;font-weight:700}.about-aka{color:var(--muted-text);font-size:13px;font-weight:400;margin-left:4px}.about-version{color:var(--muted-text);font-size:12px}.about-description{line-height:1.5;margin:12px 0}.about-links{display:flex;flex-wrap:wrap;gap:6px 16px}.about-links a{color:var(--accent);font-weight:600;text-decoration:none}.about-links a:hover{text-decoration:underline}.about-body h3{color:var(--muted-text);font-size:11px;letter-spacing:.05em;margin:18px 0 6px;text-transform:uppercase}.about-details{display:grid;gap:4px 16px;grid-template-columns:max-content 1fr;margin:0}.about-details dt{color:var(--muted-text)}.about-details dd{margin:0}.about-details kbd{background-color:var(--toolbar-bg);border:1px solid var(--toolbar-border);border-bottom-width:2px;border-radius:4px;font-family:inherit;font-size:11px;padding:0 4px}.about-footer{border-top:1px solid var(--toolbar-border);color:var(--muted-text);font-size:12px;margin-top:18px;padding-top:12px}.export-body{display:flex;flex-direction:column;gap:10px}.export-options{display:flex;flex-wrap:wrap;gap:8px;justify-content:space-between}.segmented{border:1px solid var(--toolbar-border);border-radius:6px;display:inline-flex;overflow:hidden}.segmented>button{background:0 0;border:0;color:var(--muted-text);cursor:pointer;font:inherit;font-size:12px;font-weight:600;padding:5px 10px}.segmented>button+button{border-left:1px solid var(--toolbar-border)}.segmented>button:hover{background-color:var(--button-hover)}.segmented>button.active{background-color:var(--accent);color:var(--accent-text)}.export-note{color:var(--muted-text);font-size:12px}.export-preview{border:1px solid var(--toolbar-border);border-radius:6px;flex:1 1 auto;min-height:120px;overflow:hidden}.export-actions{display:flex;gap:8px;justify-content:flex-end}.file-input{display:none}.more-menu{background-color:var(--dialog-bg);border:1px solid var(--toolbar-border);border-radius:8px;bottom:38px;box-shadow:0 8px 28px rgb(0 0 0 / .25);color:var(--console-text);font-size:13px;max-height:calc(100% - 48px);min-width:236px;overflow:auto;padding:4px;position:absolute;right:6px;z-index:800}.menu-item{align-items:center;background:0 0;border:0;border-radius:5px;color:inherit;cursor:pointer;display:flex;font:inherit;gap:8px;padding:6px 8px;text-align:left;width:100%}.menu-item:focus-visible,.menu-item:hover:not(:disabled){background-color:var(--button-hover);outline:0}.menu-item:disabled{cursor:not-allowed;opacity:.4}.menu-icon{color:var(--muted-text);display:inline-flex;font-size:14px;justify-content:center;width:16px}.menu-icon svg{transform:none!important}.menu-row{align-items:center;display:flex;gap:2px;padding:2px 2px 2px 8px}.menu-row-label{flex-grow:1}.menu-step{font-weight:600;justify-content:center;width:auto}.menu-percent{color:var(--muted-text);font-variant-numeric:tabular-nums;font-weight:400;min-width:52px}.menu-separator{background-color:var(--toolbar-border);height:1px;margin:4px 0}.history-panel{max-width:min(420px,calc(100% - 12px));width:360px}.history-title{color:var(--muted-text);font-size:11px;font-weight:600;letter-spacing:.05em;padding:4px 8px 6px;text-transform:uppercase}.history-item{justify-content:space-between}.history-label{font-family:var(--console-font);font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.history-detail{color:var(--muted-text);flex-shrink:0;font-size:11px}.history-empty,.history-hint{color:var(--muted-text);font-size:12px;padding:6px 8px}.history-hint{border-top:1px solid var(--toolbar-border);margin-top:4px}.value-menu{bottom:auto;min-width:220px;position:fixed;right:auto;z-index:850}.toast{animation:fade-in .15s ease-out;background-color:var(--console-text);border-radius:6px;bottom:44px;box-shadow:0 6px 20px rgb(0 0 0 / .25);color:var(--console-bg);font-size:12px;left:50%;max-width:calc(100% - 32px);padding:6px 12px;pointer-events:none;position:fixed;transform:translateX(-50%);z-index:860}.popped-out{align-items:center;background-color:var(--console-bg);color:var(--console-text);display:flex;inset:0;justify-content:center;position:fixed;z-index:950}.popped-out-content{align-items:center;display:flex;flex-direction:column;gap:8px;padding:16px;text-align:center}.popped-out-title{font-size:15px;font-weight:600;margin-top:8px}.popped-out-text{color:var(--muted-text);font-size:13px}@keyframes fade-in{from{opacity:0}}@keyframes dialog-in{from{opacity:0;transform:scale(.96)}}.rotated-90deg{transform:rotate(90deg)}.align-top{vertical-align:top!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.no-select{-webkit-user-select:none;user-select:none}:root{color-scheme:light;--console-font:ui-monospace,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;--console-bg:#fff;--console-text:#1f1f1f;--row-border:#f0f0f0;--arrow:#727272;--chevron:#9aa0a6;--entry-key:#881391;--preview-key:#5f6368;--string:#c41a16;--number:#1a1aa6;--null:#80868b;--header-bg:#f1f3f4;--header-text:#3c4043;--warn-bg:#fffbe5;--warn-border:#fff5c2;--warn-text:#5c3c00;--warn-icon:#e8a600;--error-bg:#fff0f0;--error-border:#ffd6d6;--error-text:#dc362e;--error-icon:#dc362e;--table-header-bg:#f3f3f3;--table-border:#d0d0d0;--toolbar-bg:#f3f3f3;--toolbar-border:#d6d6d6;--toolbar-text:#333;--muted-text:#5f6368;--button-hover:rgb(0 0 0 / 0.08);--accent:#1a73e8;--accent-hover:#1765cc;--accent-text:#fff;--divider-bg:#f3f3f3;--divider-hover-bg:#e8eaed;--divider-grip:#b0b0b0;--dialog-bg:#fff;--backdrop:rgb(0 0 0 / 0.25)}:root[data-theme=dark]{color-scheme:dark;--console-bg:#242424;--console-text:#e3e3e3;--row-border:#3a3a3a;--arrow:#9aa0a6;--chevron:#80868b;--entry-key:#5db0d7;--preview-key:#9aa0a6;--string:#f28b54;--number:#9980ff;--null:#8e8e8e;--header-bg:#2d2e30;--header-text:#c4c7c5;--warn-bg:#332b00;--warn-border:#665500;--warn-text:#ffd17a;--warn-icon:#ffd17a;--error-bg:#290000;--error-border:#5c0000;--error-text:#ff8080;--error-icon:#ff6b6b;--table-header-bg:#2e2e2e;--table-border:#4a4a4a;--toolbar-bg:#2b2b2b;--toolbar-border:#474747;--toolbar-text:#e3e3e3;--muted-text:#9aa0a6;--button-hover:rgb(255 255 255 / 0.1);--accent:#8ab4f8;--accent-hover:#aecbfa;--accent-text:#202124;--divider-bg:#2b2b2b;--divider-hover-bg:#333;--divider-grip:#6b6b6b;--dialog-bg:#2d2e30;--backdrop:rgb(0 0 0 / 0.5)}#displays{background-color:var(--console-bg);color:var(--console-text)}#displays>div{font-family:var(--console-font);font-size:calc(12px * var(--text-scale, 1));line-height:calc(16px * var(--text-scale, 1))}.console-row{border-bottom:1px solid var(--row-border);padding:2px 8px 2px 24px;position:relative;white-space:pre-wrap;word-break:break-word}.console-row>.row-icon{left:6px;line-height:0;position:absolute;top:4px}.log-error,.log-warn{margin-top:-1px}.log-warn{background-color:var(--warn-bg);border-bottom-color:var(--warn-border);border-top:1px solid var(--warn-border);color:var(--warn-text)}.log-warn>.row-icon{color:var(--warn-icon)}.log-error{background-color:var(--error-bg);border-bottom-color:var(--error-border);border-top:1px solid var(--error-border);color:var(--error-text)}.log-error>.row-icon{color:var(--error-icon)}.console-row{padding-left:calc(24px + var(--depth,0) * 16px)}.console-row>.row-icon{left:calc(6px + var(--depth,0) * 16px)}.group-header{cursor:pointer;font-weight:700}.group-header>.row-icon.arrow{top:5px}.log-assert{background-color:var(--error-bg);border-bottom-color:var(--error-border);border-top:1px solid var(--error-border);color:var(--error-text);margin-top:-1px}.log-assert>.row-icon{color:var(--error-icon)}.log-result>.row-icon{color:var(--chevron)}.trace-stack{color:var(--null);padding-left:1ch}.splash-message{color:var(--muted-text);font-size:13px;max-width:280px;text-align:center}.splash-slow{animation:show-after-delay 0s 10s both}@keyframes show-after-delay{from{visibility:hidden}to{visibility:visible}}#splash.failed .splash-progress,#splash.failed .splash-slow,.splash-error{display:none}#splash.failed .splash-error{display:block}.code-header{background-color:var(--header-bg);border-bottom:1px solid var(--row-border);color:var(--header-text);font-weight:700;padding:2px 8px;white-space:pre-wrap}.code-header.toggleable{cursor:pointer}.code-row .copy-to-editor-button{align-items:center;background-color:var(--console-bg);border:1px solid var(--toolbar-border);border-radius:4px;color:var(--toolbar-text);cursor:pointer;display:inline-flex;height:22px;justify-content:center;opacity:0;padding:0;position:absolute;right:6px;top:2px;transition:opacity .15s;width:22px}.code-row .copy-to-editor-button:focus-visible,.code-row:hover .copy-to-editor-button{opacity:1}.code-row .copy-to-editor-button:hover{background-color:var(--toolbar-bg)}@media (hover:none){.code-row .copy-to-editor-button{opacity:.8}}.notice{color:var(--null);font-style:italic}.code-row>.row-icon{color:var(--chevron)}.code-row code,.code-row pre{background:0 0!important;font-family:var(--console-font)!important;font-size:calc(12px * var(--text-scale, 1))!important;line-height:calc(16px * var(--text-scale, 1))!important;padding:0!important;text-shadow:none!important}.js-value{max-width:100%;vertical-align:top}.row-content>.js-value+.js-value{margin-left:1ch}.js-value-header.expandable{cursor:default}.js-value .expansion{padding-left:12px}.js-value .loading{color:var(--null);padding-left:12px}.arrow{display:inline-block;height:10px;position:relative;width:12px}.arrow.expandable::before{border-color:transparent transparent transparent var(--arrow);border-style:solid;border-width:4px 0 4px 6px;content:'';left:2px;position:absolute;top:1px;transform-origin:3px 4px;transition:transform .1s}.arrow.expandable.expanded::before{transform:rotate(90deg)}.entry-key{color:var(--entry-key)}.entry-key.dim{opacity:.6}.t-key{color:var(--preview-key)}.t-regexp,.t-string,.t-symbol{color:var(--string)}.t-number{color:var(--number)}.t-null{color:var(--null)}.t-function{font-style:italic}.t-node{color:var(--entry-key)}.console-table{border:1px solid var(--table-border);border-collapse:collapse;margin:2px 0 4px;white-space:nowrap}.console-table td,.console-table th{border-left:1px solid var(--table-border);max-width:300px;overflow:hidden;padding:1px 4px;text-align:left;text-overflow:ellipsis}.console-table th{background-color:var(--table-header-bg);border-bottom:1px solid var(--table-border);font-weight:400}",PACKAGE_INFO={name:"yourjs-box",version:"1.8.0",homepage:"https://westc.github.io/yourjs-box/",repoUrl:"https://github.com/westc/yourjs-box",bugsUrl:"https://github.com/westc/yourjs-box/issues"},VIEWER_IFRAME_HTML='<div id="splash" aria-label="Loading"><div class="splash-content"><span class="logo logo-large"><span class="logo-mark">JS</span><span class="logo-text">Box</span></span><div class="splash-progress"><div></div></div><div class="splash-message splash-slow">Still loading&hellip;</div><div class="splash-message splash-error">JS Box couldn&rsquo;t load. Please check your connection and reload the page.</div></div></div><div id="vueApp" v-cloak><input type="file" ref="fileInput" class="file-input" accept=".js,.mjs,.cjs,.ts,.mts,.cts,.txt,text/javascript,text/plain" tabindex="-1" aria-hidden="true" @change="onFileChosen"><div id="main" ref="main" :class="mainElemClassNames" :style="mainElemStyles" @mousedown="onMainElemMouseDown"><div id="displays"><div ref="displaysScroller" @scroll="onDisplaysScroll"><template v-for="display in displays"><div v-if="display.type === \'prism\'"><div v-if="display.isHidden" class="code-header toggleable no-select" @click="display.isCodeShown = !display.isCodeShown" :title="display.isCodeShown ? \'Hide Code\' : \'Show Code\'"><span :class="[\'arrow\', \'expandable\', display.isCodeShown ? \'expanded\' : \'\']"></span>{{ display.header || \'Hidden code\' }}</div><div v-else-if="display.header" class="code-header">{{ display.header }}</div><div v-if="display.isCodeShown" class="console-row code-row"><span class="row-icon"><icon name="chevron"></icon></span><prism :language="language" :code="display.value" :is-dark="theme === \'dark\'" match-braces></prism><button class="copy-to-editor-button" title="Copy to editor" @click="copyToEditor(display.value)"><icon name="copyToEditor"></icon></button></div></div><div v-if="display.type === \'log\' &amp;&amp; !isInCollapsedGroup(display)" :class="[\'console-row\', \'log-\' + display.key, display.groupId ? \'group-header\' : \'\']" :style="{\'--depth\': display.groupIds.length}" :title="display.name" @click="onLogRowClick(display, $event)"><span v-if="display.key === \'error\' || display.key === \'assert\'" class="row-icon"><icon name="consoleError"></icon></span><span v-else-if="display.key === \'warn\'" class="row-icon"><icon name="consoleWarning"></icon></span><span v-else-if="display.key === \'result\'" class="row-icon"><icon name="result"></icon></span><span v-else-if="display.groupId" :class="[\'row-icon\', \'arrow\', \'expandable\', display.isCollapsed ? \'\' : \'expanded\']"></span><div class="row-content"><table v-if="display.table" class="console-table"><thead><tr><th v-for="header in display.table.headers">{{ header }}</th></tr></thead><tbody><tr v-for="row in display.table.rows"><td>{{ row.index }}</td><td v-for="cell in row.cells"><template v-if="cell"><span v-for="part in cell.parts" :class="\'t-\' + part[0]">{{ part[1] }}</span></template></td></tr></tbody></table><js-value v-for="(description, index) in display.descriptions" :description="description" :key-path="[]" :path="[display.logId, index]"></js-value><div v-if="display.stack" class="trace-stack">{{ display.stack }}</div></div></div><div v-if="display.type === \'notice\'" class="console-row notice">{{ display.message }}</div><div v-if="display.type === \'error\'" class="console-row log-error"><span class="row-icon"><icon name="consoleError"></icon></span><div class="row-content">{{ display.message }}</div></div></template></div></div><div class="divider" ref="mainDivider"></div><div id="editor"><ace-editor ref="editor" v-model="jsCode" :language="language" :theme="theme" :font-size="Math.round(12 * textScale)" @key-combo="onEditorKeyCombo" @history-key="onEditorHistoryKey" height="100%"></ace-editor></div></div><div id="bottomNav"><div class="brand"><button class="logo-button" title="About JS Box" @click="openAbout(\'about\')"><span class="logo"><span class="logo-mark">JS</span><span class="logo-text">Box</span></span></button> <span class="runner-badge" :title="runnerMode === \'window\' ? \'Code runs directly in this page\' : \'Code runs in a Web Worker (no DOM access)\'">{{ runnerMode === \'window\' ? \'Window\' : \'Worker\' }}</span></div><div class="buttons"><template v-for="bottomButton in bottomButtons"><span v-if="bottomButton.isSeparator" class="separator"></span> <button v-else :class="bottomButton.className" @click="bottomButton.callback.call(this, $event)" :title="bottomButton.title" :disabled="bottomButton.disableIf &amp;&amp; bottomButton.disableIf.call(this)"><icon :name="bottomButton.iconName"></icon><span v-if="bottomButton.label" class="label">{{ bottomButton.label }}</span></button></template></div></div><div v-if="isMenuOpen" class="more-menu" role="menu" aria-label="More" ref="moreMenu" @keydown="onMenuKeyDown"><div class="menu-row" role="group" aria-label="Text size"><span class="menu-row-label">Text size</span> <button class="menu-item menu-step" role="menuitem" title="Smaller text" aria-label="Smaller text" :disabled="!canShrinkText" @click="changeTextScale(-1)">A&minus;</button> <button class="menu-item menu-step menu-percent" role="menuitem" title="Reset the text size" aria-label="Reset the text size" @click="setTextScale(1)">{{ Math.round(textScale * 100) }}%</button> <button class="menu-item menu-step" role="menuitem" title="Bigger text" aria-label="Bigger text" :disabled="!canGrowText" @click="changeTextScale(1)">A+</button></div><div class="menu-separator"></div><button class="menu-item" role="menuitem" @click="openFile()"><span class="menu-icon"><icon name="open"></icon></span>Open&hellip;</button> <button class="menu-item" role="menuitem" @click="saveFile()"><span class="menu-icon"><icon name="save"></icon></span>Save&hellip;</button><div class="menu-separator"></div><button v-if="isPopOut" class="menu-item" role="menuitem" @click="closeMenu(); bringBack()"><span class="menu-icon"><icon name="popIn"></icon></span>Bring back into the page</button> <button v-else class="menu-item" role="menuitem" @click="popOut()"><span class="menu-icon"><icon name="popOut"></icon></span>Pop out into a window</button> <button class="menu-item" role="menuitem" @click="closeMenu(); openAbout(\'html\')"><span class="menu-icon"><icon name="code"></icon></span>Copy as HTML&hellip;</button> <button class="menu-item" role="menuitem" @click="closeMenu(); resetConsole()"><span class="menu-icon"><icon name="refresh"></icon></span>Reset&hellip;</button><div class="menu-separator"></div><button class="menu-item" role="menuitem" @click="closeMenu(); openAbout(\'about\')"><span class="menu-icon"><icon name="info"></icon></span>About JS Box</button></div><div v-if="isHistoryOpen" class="more-menu history-panel" role="menu" aria-label="History" ref="historyPanel" @keydown="onMenuKeyDown"><div class="history-title">History</div><div v-if="!historyEntries.length" class="history-empty">Code that you run will show up here.</div><button v-for="entry in historyEntries" class="menu-item history-item" role="menuitem" :title="commandHistory[entry.index]" @click="recallHistory(entry.index)"><span class="history-label">{{ entry.label }}</span> <span class="history-detail">{{ entry.detail }}</span></button><div class="history-hint">Tip: press &uarr; at the start of the editor (or &darr; at the end) to go through the history.</div></div><div v-if="valueMenu" class="more-menu value-menu" role="menu" aria-label="Value" ref="valueMenu" :style="{left: valueMenu.x + \'px\', top: valueMenu.y + \'px\'}" @keydown="onMenuKeyDown"><button class="menu-item" role="menuitem" @click="copyValueAsJson()"><span class="menu-icon"><icon name="copy"></icon></span>Copy as JSON</button> <button class="menu-item" role="menuitem" @click="saveValueAsJson()"><span class="menu-icon"><icon name="save"></icon></span>Save as JSON&hellip;</button> <button class="menu-item" role="menuitem" @click="storeValueAsGlobal()"><span class="menu-icon"><icon name="variable"></icon></span>Store as global variable</button> <button v-if="valueMenu.propertyPath" class="menu-item" role="menuitem" @click="copyPropertyPath()"><span class="menu-icon"><icon name="path"></icon></span>Copy property path</button><template v-if="!valueMenu.isPrimitive"><div class="menu-separator"></div><button class="menu-item" role="menuitem" @click="refreshValue()"><span class="menu-icon"><icon name="refresh"></icon></span>Refresh</button></template></div><div v-if="toast" class="toast" role="status">{{ toast.message }}</div><div v-if="isPoppedOut" class="popped-out"><div class="popped-out-content"><span class="logo logo-medium"><span class="logo-mark">JS</span><span class="logo-text">Box</span></span><div class="popped-out-title">This console is open in a separate window</div><div class="popped-out-text">Its code still runs in this page.</div><div class="dialog-buttons"><button class="dialog-button" @click="focusPopOut">Show the window</button> <button class="dialog-button primary" @click="requestPopIn">Bring it back</button></div></div></div><div v-if="isAboutOpen" class="dialog-backdrop" @mousedown.self="closeAbout" @keydown.esc="closeAbout"><div :class="[\'dialog\', \'about-dialog\', aboutTab === \'html\' ? \'is-export\' : \'\']" role="dialog" aria-modal="true" aria-label="About JS Box"><div class="about-header"><div class="tabs" role="tablist"><button role="tab" :aria-selected="aboutTab === \'about\'" :class="[\'tab\', aboutTab === \'about\' ? \'active\' : \'\']" @click="aboutTab = \'about\'">About</button> <button role="tab" :aria-selected="aboutTab === \'html\'" :class="[\'tab\', aboutTab === \'html\' ? \'active\' : \'\']" @click="aboutTab = \'html\'">Copy as HTML</button></div><button class="close-button" ref="aboutCloseButton" title="Close" @click="closeAbout"><icon name="close"></icon></button></div><div v-if="aboutTab === \'about\'" class="about-body"><div class="about-title"><span class="logo logo-medium"><span class="logo-mark">JS</span><span class="logo-text">Box</span></span><div><div class="about-name">YourJS Box <span class="about-aka">aka JS Box</span></div><div class="about-version">Version {{ packageInfo.version }}</div></div></div><p class="about-description">An interactive JavaScript console that can be embedded in any web page with a single script tag.</p><div class="about-links"><a :href="packageInfo.homepage" target="_blank" rel="noopener">Website</a> <a :href="packageInfo.repoUrl" target="_blank" rel="noopener">GitHub</a> <a :href="packageInfo.repoUrl + \'#readme\'" target="_blank" rel="noopener">Documentation</a> <a :href="packageInfo.bugsUrl" target="_blank" rel="noopener">Report an issue</a></div><h3>This console</h3><dl class="about-details"><dt>Code runs in</dt><dd>{{ runnerDescription }}</dd><dt>Theme</dt><dd>{{ themeDescription }}</dd><dt>Language</dt><dd>{{ isTypeScript ? \'TypeScript (types are removed by Babel, not checked)\' : \'JavaScript\' }}</dd><dt>Code blocks run as</dt><dd>{{ blockTypeDescription }}</dd><dt>Imports</dt><dd>{{ importsUrl ? \'Packages imported by name load from \' + importsUrl.replace(\'{specifier}\', \'\u2026\') : \'Only URLs and paths can be imported\' }}</dd><dt>Results</dt><dd>{{ showResults ? \'The value of the last expression is shown\' : \'Not shown\' }}</dd><dt>Layout</dt><dd>{{ layoutDescription }}</dd></dl><h3>Keyboard shortcuts</h3><dl class="about-details"><dt><kbd>{{ modKey }}</kbd> + <kbd>Enter</kbd></dt><dd>Run the next block of code</dd><dt><kbd>&uarr;</kbd> / <kbd>&darr;</kbd></dt><dd>Go through the code that was run (at the very start or end of the editor)</dd><dt><kbd>{{ modKey === \'Ctrl\' ? \'Alt\' : \'&#8997;\' }}</kbd> + <kbd>H</kbd></dt><dd>Show the history</dd><dt><kbd>Esc</kbd></dt><dd>Close this window, the menu or full screen</dd></dl><div class="about-footer">MIT License &copy; 2023-present Chris West &middot; Built with {{ builtWith }}</div></div><div v-else class="about-body export-body"><div class="export-options"><div class="segmented" role="radiogroup" aria-label="Code"><button v-for="option in exportCodeOptions" role="radio" :aria-checked="exportCode === option.value" :class="exportCode === option.value ? \'active\' : \'\'" @click="exportCode = option.value">{{ option.label }}</button></div><div class="segmented" role="radiogroup" aria-label="Format"><button v-for="option in exportFormatOptions" role="radio" :aria-checked="exportFormat === option.value" :class="exportFormat === option.value ? \'active\' : \'\'" @click="exportFormat = option.value">{{ option.label }}</button></div></div><div class="export-note">{{ exportNote }}</div><div class="export-preview"><ace-editor :model-value="exportHtml" language="html" :theme="theme" height="100%" :read-only="true"></ace-editor></div><div class="export-actions"><button class="dialog-button" @click="downloadExport">Download page</button> <button class="dialog-button primary" @click="copyExport">{{ copyLabel }}</button></div></div></div></div><div v-if="dialog" class="dialog-backdrop" @mousedown.self="closeDialog(false)" @keydown.esc="closeDialog(false)"><div class="dialog" role="alertdialog" aria-modal="true" :aria-label="dialog.title"><div class="dialog-title">{{ dialog.title }}</div><div class="dialog-message">{{ dialog.message }}</div><div class="dialog-buttons"><button class="dialog-button" @click="closeDialog(false)">Cancel</button> <button class="dialog-button primary" ref="dialogConfirmButton" @click="closeDialog(true)">{{ dialog.confirmText }}</button></div></div></div></div>',OWN_URL=document.currentScript?.src??"",ORIGINAL_CONSOLE=window[Symbol.for("yourjs-box.originalConsole")]??={...console},LIBRARY_VERSIONS={"@babel/standalone":"7.29.9","ace-builds":"1.44.0",acorn:"8.18.0","prism-themes":"1.9.0",prismjs:"1.30.0",vue:"3.5.43"},DEFAULT_LIBRARIES_URL="https://unpkg.com/{name}@{version}/";function getLibraryFileUrl(librariesUrl,name,path){var librariesUrl=librariesUrl.replace(/\{(name|version)\}/g,(_,key)=>"name"===key?name:LIBRARY_VERSIONS[name]).replace(/\/?$/,"/");return new URL(librariesUrl+path,document.baseURI).href}const DEFAULT_IMPORTS_URL="https://esm.sh/{specifier}";function resolveUrlTemplate(template){var index=template.indexOf("{"),prefix=index<0?template:template.slice(0,index);return new URL(prefix||"./",document.baseURI).href.replace(/\/$/,prefix.endsWith("/")||!prefix?"/":"")+(index<0?"":template.slice(index))}const RELAYABLE_FUNCS={viewer:["appendLog","appendError","clearDisplays","onCodeRan","onStoredAsGlobal","onValueJson","updateDescriptionFor"],runner:["clearLogs","getValueAsJson","refreshDescription","reset","runCode","sendDescriptionFor","storeAsGlobal"],host:["focusPopOut","popIn","popOut","requestPopIn","setMaximized"]};function relayMessage(data,targets){var{target,func,args}=Object(data),targets=targets[target];targets&&RELAYABLE_FUNCS[target].includes(func)&&Array.isArray(args)?targets.apply(func,args):ORIGINAL_CONSOLE.error("Unhandled message sent to main handler:",data)}function createRunner(e,t){const{mode:n}=t,r=t.ownUrl||("worker"===n?self.location.href:""),o={};let s=0,i=0,c=!0,a;const l={},u={},f={},p={};let d=[],g=0;const h="yourjs-box.result."+Math.random().toString(36).slice(2),m=(globalThis[Symbol.for(h)]=v,[]);for(const e of["assert","clear","count","countReset","debug","dir","dirxml","error","group","groupCollapsed","groupEnd","info","log","table","time","timeEnd","timeLog","trace","warn"]){const t=console[e];if("function"==typeof t){const n=function(...n){return y(e,n),t.apply(this,arguments)};console[e]=n,m.push({key:e,original:t,wrapper:n})}}function y(t,n){var r=n.length&&void 0!==n[0]?""+n[0]:"default";if("clear"===t)K(),d=[],e({target:"viewer",func:"clearDisplays",args:[!0]});else if("assert"===t){if(!n[0]){const e=n.slice(1);b("assert",e.length?"string"==typeof e[0]?["Assertion failed: "+e[0],...e.slice(1)]:["Assertion failed:",...e]:["Assertion failed: console.assert"])}}else if("count"===t)f[r]=(f[r]||0)+1,b("count",[r+": "+f[r]]);else if("countReset"===t)Object.hasOwn(f,r)?f[r]=0:b("warn",[`Count for '${r}' does not exist`]);else if("time"===t)Object.hasOwn(p,r)?b("warn",[`Timer '${r}' already exists`]):p[r]=performance.now();else if("timeLog"===t||"timeEnd"===t){if(!Object.hasOwn(p,r))return b("warn",[`Timer '${r}' does not exist`]);const e=performance.now()-p[r];"timeEnd"===t&&delete p[r],b(t,[r+`: ${+e.toFixed(3)} ms`,..."timeLog"===t?n.slice(1):[]])}else if("trace"===t){const e=w((new Error).stack??"").split("\n").slice(1).join("\n");b("trace",n.length?n:["console.trace"],{stack:e})}else if("group"===t||"groupCollapsed"===t){const e=""+ ++g;b(t,n.length?n:["console.group"],{groupId:e,isCollapsed:"groupCollapsed"===t}),d.push(e)}else if("groupEnd"===t)d.pop();else{const e="table"===t?A(n[0],n[1]):null;b(t,e?n.slice(0,1):n,{table:e})}}function b(t,n,r,i=0){var c=""+ ++s;o[c]=n.map(e=>({...C(e,i),value:e})),e({target:"viewer",func:"appendLog",args:[{logId:c,key:t,descriptions:o[c].map(S(["value"])),groupIds:d.slice(),...r}]})}function v(e){void 0!==e&&b("result",[e],{},"string"==typeof e?1:0)}function $(e){O(void 0!==e.error?e.error:e.message)}function x(e){O(e.reason,!0)}function j(){removeEventListener("error",$),removeEventListener("unhandledrejection",x),delete globalThis[Symbol.for(h)];for(var{key:e,original:t,wrapper:n}of m)console[e]===n&&(console[e]=t);K()}function O(t,n){var r="classic"===a&&"SyntaxError"===t?.name?/\bawait\b/.test(t.message)?"top-level await":/\bimport\b/.test(t.message)?"import statements":null:null,r=r?`
3
3
  (To use ${r}, add data-block-type="module" to the script tag.)`:"";e({target:"viewer",func:"appendError",args:[{message:(n?"Uncaught (in promise) ":"Uncaught ")+w(t?.stack??""+(t?.message??t))+r}]})}function w(e){return(""+e).split("\n").filter(e=>!(r&&/^\s*at\b/.test(e)&&e.includes(r))).join("\n").replace(/(snippet-\d+\.[jt]s):(\d+):(\d+)/g,(e,t,n,r)=>{n=+n,r=+r;var o=l[t];return o&&n===o.line&&r>o.column&&(r=Math.max(o.column,r-o.shift)),[n,r]=E(u[t],n,r),t+`:${n}:`+r})}function E(e,t,n){var r=e?.[t-1];let o;for(const e of r??[]){if(e[0]>n-1)break;o=e}return o?[o[1]+1,o[2]+1+(n-1-o[0])]:[t,n]}function S(e,t){if(!t)return t=>S(e,t);var n={...t};for(const t of e)delete n[t];return n}function A(e,t){if(null===e||"object"!=typeof e)return null;const n="Value",r=[];let o=!1;const s=Object.keys(e).map(t=>{var n=e[t],s={index:t,values:{},hasValue:!1};if(null===n||"object"!=typeof n&&"function"!=typeof n)o=!0,s.hasValue=!0,s.value=n;else for(const e of Object.keys(n))r.includes(e)||r.push(e),s.values[e]=n[e];return s}),i=Array.isArray(t)?t.map(e=>""+e):r,c=o&&!Array.isArray(t);return{headers:["(index)",...i,...c?[n]:[]],rows:s.map(({index:e,values:t,hasValue:n,value:r})=>({index:e,cells:[...i.map(e=>Object.hasOwn(t,e)?C(t[e],2):null),...c?[n?C(r,2):null]:[]]}))}}function k(e){var t;return null==e?""+e:"object"==(t=typeof e)||"undefined"==t?Object.prototype.toString.call(e).slice(8,-1):t}function N(e,t){try{const t=Object.getPrototypeOf(e)?.constructor?.name;if(t&&"string"==typeof t)return t}catch(e){}return t}addEventListener("error",$),addEventListener("unhandledrejection",x);const L=5,T=100;function C(e,t=0,n=!1){var r=k(e),o="function"!==r&&r===r.toLowerCase(),s=void 0;return{typeName:r,isPrimitive:o,parts:n?[["text","Object"!==r?r:N(e,r)]]:R(e,t,r)}}function R(e,t,n=k(e)){if("string"===n)return t?[["string",D(e=1<t&&100<e.length?e.slice(0,99)+"\u2026":e)]]:[["text",e]];if("number"===n)return[["number",Object.is(e,-0)?"-0":""+e]];if("bigint"===n)return[["number",e+"n"]];if("boolean"===n)return[["number",""+e]];if("null"===n||"undefined"===n)return[["null",n]];if("symbol"===n)return[["symbol",e.toString()]];if("function"===n)return M(e,t);try{return U(e,t,n)}catch(e){return[["text",n]]}}function D(e){var t=JSON.stringify(e);return e.includes("'")?t:`'${t.slice(1,-1).replace(/\\"/g,'"')}'`}function M(e,t){let n="";try{n=Function.prototype.toString.call(e)}catch(e){}var r=/^class\b/.test(n);return t?1<t?[["function","\u0192"]]:[["function",r?"class "+e.name:`\u0192 ${e.name}()`]]:[["text",r?n:n.replace(/^(async\s+)?function\b\s*/,"$1\u0192 ")]]}function U(e,t,n){var r=N(e,n),o=/^Array(?:[^a-z]|$)|[^A-Z]Array$/.test(n);if("Date"===n)return[["text",isNaN(e)?"Invalid Date":Date.prototype.toString.call(e)]];if("RegExp"===n)return[["regexp",""+e]];if("Promise"===n)return[["text",r+" {\u2026}"]];if("undefined"!=typeof Node&&e instanceof Node)return e.nodeType===Node.ELEMENT_NODE?[["node",e.localName+(e.id?"#"+e.id:"")+[...e.classList].map(e=>"."+e).join("")]]:e.nodeType===Node.TEXT_NODE?[["string",D(e.data)]]:[["node",e.nodeName]];if(e instanceof Error)return[["text",t?e.name+": "+e.message:w(e.stack??""+e)]];if(1<t)return o?[["text",`${r}(${e.length})`]]:"Map"===n||"Set"===n?[["text",`${r}(${e.size})`]]:[["text","Object"===r?"{\u2026}":r]];const s=[],i=(e,t,n)=>{e.forEach((e,t)=>{t&&s.push(["text",", "]),n(e)}),t>e.length&&s.push(["text",(e.length?", ":"")+"\u2026"])};if(o){const t=e.length;s.push(["text","Array"===n&&"Array"===r?`(${t}) [`:`${r}(${t}) [`]),i(Array.from({length:Math.min(t,T)},(e,t)=>t),t,t=>s.push(...t in e?R(e[t],2):[["null","empty"]])),s.push(["text","]"])}else if("Map"===n||"Set"===n){const t=[...e].slice(0,T);s.push(["text",`${r}(${e.size}) {`]),i(t,e.size,e=>{"Map"===n?s.push(...R(e[0],2),["text"," => "],...R(e[1],2)):s.push(...R(e,2))}),s.push(["text","}"])}else{const t=Object.keys(e);"Object"!==r&&s.push(["text",r+" "]),"Number"===n||"String"===n||"Boolean"===n?s.push(["text","{"],...R(e.valueOf(),2),["text","}"]):(s.push(["text","{"]),i(t.slice(0,L),t.length,t=>{var n=Object.getOwnPropertyDescriptor(e,t);s.push(["key",t],["text",": "],..."value"in n?R(n.value,2):[["text","(\u2026)"]])}),s.push(["text","}"]))}return s}function P(e,t=e){const n=k(e),r=[],o=[],s=[],i=[];let c=!1;if(null!==e&&("object"==typeof e||"function"==typeof e)){try{if("Map"===n){for(const[t,n]of[...e])r.push([R(t,2).map(e=>e[1]).join(""),C(n,1)]),o.push({value:n});c=!0}else if("Array"!==n&&"function"!==n&&"function"==typeof e[Symbol.iterator]){let t=0;for(const n of e)r.push([""+t,C(n,1)]),o.push({value:n}),++t;c=!0}}catch(e){r.length=o.length=0}if(!c)for(const n of Object.getOwnPropertyNames(e))try{const s=Object.getOwnPropertyDescriptor(e,n),i="value"in s?s.value:Reflect.get(e,n,t);r.push([n,C(i,1),s.enumerable]),o.push({value:i})}catch(e){}var a=Object.getPrototypeOf(e);null!==a&&(s.push(["[[Prototype]]",C(a,1,!0)]),i.push({value:a,receiver:t}))}return{entries:r,protoEntries:s,entriesArePropertyKeys:!c,$entries:o,$protoEntries:i}}async function I(t,r){const{blockType:o,resultRange:s,language:c,sourceMap:f,compileError:p}=Object(r),d=`snippet-${++i}.`+("typescript"===c?"ts":"js");if(Array.isArray(f)&&(u[d]=f),Array.isArray(s)){const[e,n]=s,r=`globalThis[Symbol.for(${JSON.stringify(h)})]((`,o=t.slice(0,e).split("\n");l[d]={line:o.length,column:o[o.length-1].length+1,shift:r.length},t=t.slice(0,e)+r+t.slice(e,n)+"))"+t.slice(n)}var r=t+`
4
4
  //# sourceURL=`+d;a="module"===o?"module":"classic";try{if(p){const{message:e,line:t,column:n}=p;O({name:"SyntaxError",message:""+e,stack:`SyntaxError: ${e}
5
- at ${d}:${+t}:`+ +n})}else if("module"===o)await import("data:text/javascript;charset=utf-8,"+encodeURIComponent(r));else if("worker"===n)J(r);else{const e=document.createElement("script");e.textContent=r,document.head.appendChild(e),e.remove()}}catch(e){O(e)}a=void 0,e({target:"viewer",func:"onCodeRan",args:[]})}function J(e){if(c)try{return importScripts("data:text/javascript;charset=utf-8,"+encodeURIComponent(e))}catch(e){if("NetworkError"!==e?.name)throw e;c=!1}var t=URL.createObjectURL(new Blob([e],{type:"text/javascript"}));try{importScripts(t)}finally{URL.revokeObjectURL(t)}}function V(e){F(e,!1)}function z(e){F(e,!0)}function F(t,n){var r=B(t),o,n;r&&(o=P(r.value,"receiver"in r?r.receiver:r.value),Object.assign(r,o),n=n?C(r.value,2<t.length?1:0,"protoEntries"===t[t.length-2]):{},e({target:"viewer",func:"updateDescriptionFor",args:[t,{...S(["$entries","$protoEntries"],o),...n}]}))}function B(e){let t=o;return e.forEach((e,n)=>{t=t?.[n&&n%2==0?"$"+e:e]}),t}function G(t,n){var t=B(t);let o;try{o=t?_(t.value):{error:"The value is no longer available."}}catch(e){o={error:`The value couldn't be converted to JSON (${e?.message??e}).`}}e({target:"viewer",func:"onValueJson",args:[{requestId:n,...o}]})}function _(e){let t=0;const n=[],r=JSON.stringify(e,function(e,r){for(;n.length&&n[n.length-1].converted!==this;)n.pop();if("bigint"==typeof r)return""+r;if(null!==r&&"object"==typeof r){const e=r;if(n.some(t=>t.original===e))return void t++;(r instanceof Map||r instanceof Set)&&(r=[...r]),n.push({original:e,converted:r})}return r},2);return void 0===r?{error:"This value can't be represented as JSON.",circularCount:t}:{json:r,circularCount:t}}function q(t){var t=B(t);if(t){let r=1;for(;"temp"+r in globalThis;)r++;globalThis["temp"+r]=t.value,e({target:"viewer",func:"onStoredAsGlobal",args:["temp"+r]})}}function K(){for(const e of Object.keys(o))delete o[e];d=[]}return{clearLogs:K,destroy:j,getValueAsJson:G,refreshDescription:z,runCode:I,sendDescriptionFor:V,storeAsGlobal:q}}function createWorkerRunner(onMessage){const WORKER_SOURCE="(function(){var runner = ("+createRunner+')(function(m) { postMessage(m); }, {mode: "worker"});onmessage = function(e) {var d = e.data;if (d && Object.prototype.hasOwnProperty.call(runner, d.func) && Array.isArray(d.args)) {runner[d.func].apply(null, d.args);}};postMessage({target: "main", func: "ready"});})();';let canUseDataUrl=!0,blobUrl,worker,isReady,pendingMessages;function start(){isReady=!1,pendingMessages=[];var url=canUseDataUrl?"data:text/javascript;charset=utf-8,"+encodeURIComponent(WORKER_SOURCE):blobUrl??=URL.createObjectURL(new Blob([WORKER_SOURCE],{type:"text/javascript"}));try{worker=new Worker(url)}catch(e){if(canUseDataUrl)return canUseDataUrl=!1,start();throw e}const thisWorker=worker;worker.onmessage=e=>{if(thisWorker===worker)if("main"===e.data?.target&&"ready"===e.data.func){isReady=!0;for(const message of pendingMessages.splice(0))worker.postMessage(message)}else onMessage(e.data)},worker.onerror=e=>{var e;thisWorker===worker&&!isReady&&canUseDataUrl&&(e.preventDefault(),canUseDataUrl=!1,e=pendingMessages,worker.terminate(),start(),pendingMessages.push(...e))}}return start(),{destroy(){worker.terminate(),blobUrl&&URL.revokeObjectURL(blobUrl)},apply(func,args){"reset"===func?(worker.terminate(),start()):isReady?worker.postMessage({func:func,args:args}):pendingMessages.push({func:func,args:args})}}}function createWindowRunner(onMessage){const runner=createRunner(onMessage,{mode:"window",ownUrl:OWN_URL});return{destroy(){runner.destroy()},apply(func,args){"reset"===func?runner.clearLogs():runner[func](...args)}}}function createConsole({code,dataset,height,insert}){const runnerMode="window"===dataset.runner?"window":"worker",blockType="module"===dataset.blockType?"module":"classic",language="typescript"===dataset.language?"typescript":"javascript",showResults="false"!==dataset.showResults,importsUrl=null==dataset.importsUrl?DEFAULT_IMPORTS_URL:dataset.importsUrl&&resolveUrlTemplate(dataset.importsUrl),libraryUrl=getLibraryFileUrl.bind(null,dataset.librariesUrl||DEFAULT_LIBRARIES_URL);let inlineViewer,popOutViewer=null,popOutWindow=null,popOutWatcher,activeViewer;var sendToViewer=data=>relayMessage(data,{viewer:activeViewer});const runner=("window"==runnerMode?createWindowRunner:createWorkerRunner)(sendToViewer),theme=/^(light|dark)$/.test(dataset.theme)?dataset.theme:matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light",hostFuncs={setMaximized(isMaximized){var{style}=inlineViewer.iframe;isMaximized?(inlineViewer.normalCssText??=style.cssText,Object.assign(style,{position:"fixed",inset:"0",width:"100%",height:"100%",zIndex:"2147483647"})):null!=inlineViewer.normalCssText&&(style.cssText=inlineViewer.normalCssText,inlineViewer.normalCssText=null)},popOut(state){if(popOutWindow)popOutWindow.focus();else{var rect=inlineViewer.iframe.getBoundingClientRect(),width=Math.max(820,Math.round(rect.width)),rect=Math.max(560,Math.round(rect.height));const newWindow=open("","_blank",`popup,width=${width},height=`+rect);newWindow?(popOutWindow=newWindow,popOutViewer=createViewer(newWindow,state),newWindow.yourjsBoxPopIn=state=>newWindow===popOutWindow&&hostFuncs.popIn(state),activeViewer=popOutViewer,inlineViewer.call("setPoppedOut",!0),popOutWatcher=setInterval(()=>{newWindow.closed&&setTimeout(()=>newWindow===popOutWindow&&hostFuncs.popIn(null),300)},500)):inlineViewer.call("onPopOutFailed")}},popIn(state){var oldWindow=popOutWindow;oldWindow&&(clearInterval(popOutWatcher),popOutWindow=null,popOutViewer.dispose(),popOutViewer=null,(activeViewer=inlineViewer).call("setPoppedOut",!1,state),oldWindow.closed||oldWindow.close())},requestPopIn(){popOutViewer&&popOutViewer.call("popIn")},focusPopOut(){popOutWindow?.focus()}},closePopOut=()=>popOutWindow?.close();function createViewer(targetWindow,state){return createCallableFrame({jsCode(){let mountedApp;const IS_MISSING_LIBRARIES=!window.Vue||!window.ace||!window.Prism,Prism=(IS_MISSING_LIBRARIES&&document.querySelector("#splash").classList.add("failed"),window.Prism),MIN_LOADING_TIME=(delete window.Prism,Prism?.plugins.autoloader.loadLanguages("javascript"),1e3),POP_IN_FUNCTION_NAME="yourjsBoxPopIn",TEXT_SCALES=[.75,.9,1,1.15,1.3,1.5,1.75,2],TEXT_SCALE_STORAGE_KEY="yourjs-box.textScale";function loadTextScale(){try{var e=+localStorage.getItem("yourjs-box.textScale");return TEXT_SCALES.includes(e)?e:1}catch(e){return 1}}const NARROW_WIDTH=600;function getAutoDividerOrient(){return innerWidth<600?"horizontal":"vertical"}function init(e,t,i){if(!IS_MISSING_LIBRARIES){if("typescript"===i.language&&!window.Babel)return document.querySelector("#splash").classList.add("failed");Prism.plugins.autoloader.loadLanguages(i.language);const s=t.hidePrefix??"",o=matchMedia("(prefers-color-scheme: dark)"),r=unindentMin(e),{visibleCode:n,hiddenGroups:a}=extractHiddenGroups(r,s),l=/Mac|iPhone|iPad/.test(navigator.platform);mountedApp=Vue.createApp({data:()=>({displays:[],hidePrefix:s,hiddenGroups:a.map(e=>({...e})),runnerMode:i.runnerMode,importsUrl:i.importsUrl,originalCode:r,fileName:null,blockType:i.blockType,language:i.language,showResults:i.showResults,packageInfo:i.packageInfo,libraryVersions:i.libraryVersions,runHistory:[],isAboutOpen:!1,aboutTab:"about",exportCode:"current",exportFormat:"snippet",copyLabel:"Copy",runningCount:0,dialog:null,isDisplaysScrolledToBottom:!0,forcedTheme:/^(light|dark)$/.test(t.theme)?t.theme:null,prefersDark:o.matches,runCount:0,jsCode:n,isDividerOrientAuto:!/^(horizontal|vertical)$/.test(t.dividerOrient),dividerOrient:/^(horizontal|vertical)$/.test(t.dividerOrient)?t.dividerOrient:getAutoDividerOrient(),isMovingDivider:!1,dividerPct:"50%",dividerSize:"8px",tempDividerPct:null,isMenuOpen:!1,isHistoryOpen:!1,commandHistory:[],historyIndex:null,historyDraft:null,valueMenu:null,toast:null,textScale:loadTextScale(),isFullscreen:!1,isMaximized:!1,isPopOut:i.isPopOut,isPoppedOut:!1,...i.popOutState??{}}),computed:{theme(){return this.forcedTheme??(this.prefersDark?"dark":"light")},modKey:()=>l?"\u2318":"Ctrl",runnerDescription(){return"window"===this.runnerMode?"This page (it can use the page's globals and DOM)":"A Web Worker (isolated from the page, no DOM)"},themeDescription(){return`${"dark"===this.theme?"Dark":"Light"} (${this.forcedTheme?"set by data-theme":"follows your system"})`},isTypeScript(){return"typescript"===this.language},builtWith(){var e=this.libraryVersions,e=["Vue "+e.vue,"Ace "+e["ace-builds"],"Prism "+e.prismjs,"Acorn "+e.acorn,...this.isTypeScript?["Babel "+e["@babel/standalone"]]:[]];return e.slice(0,-1).join(", ")+" and "+e[e.length-1]},blockTypeDescription(){return"module"===this.blockType?"Modules (top-level await and imports work, declarations stay in each block)":"Classic scripts (top-level declarations are shared between blocks)"},collapsedGroupIds(){return new Set(this.displays.filter(e=>e.groupId&&e.isCollapsed).map(e=>e.groupId))},layoutDescription(){return("vertical"===this.dividerOrient?"Editor beside the console":"Editor below the console")+(this.isDividerOrientAuto?" (automatic)":"")},exportCodeOptions:()=>[{value:"current",label:"Current code",note:"The code that already ran followed by the code in the editor."},{value:"original",label:"Original code",note:"The code this console started with."},{value:"blank",label:"Blank",note:"An empty console with the same settings."}],exportFormatOptions:()=>[{value:"snippet",label:"Embed snippet"},{value:"page",label:"Full page"}],exportNote(){return this.exportCodeOptions.find(e=>e.value===this.exportCode).note},originalGroups(){return extractHiddenGroups(this.originalCode,this.hidePrefix)},exportJsCode(){return"original"===this.exportCode?this.originalCode:"blank"===this.exportCode?"":this.currentCode},currentCode(){const e=this.runHistory.slice(),t=this.hiddenGroups.slice();let i=this.runCount;var s=()=>{for(;t.length&&t[0].runCount<=i;)e.push(t.shift().allLines)};s();for(const t of parseJSCodeGroups(this.jsCode))t.allLines.trim()&&(e.push(t.allLines),i++,s());return e.push(...t.map(e=>e.allLines)),joinCodeBlocks(e)},exportDataset(){const{librariesUrl:e,...i}=t;return i},exportHtml(){return buildConsoleHtml({code:this.exportJsCode,dataset:this.exportDataset,packageInfo:this.packageInfo,isFullPage:"page"===this.exportFormat})},bottomButtons(){var e=this.isFullscreen||this.isMaximized;return[{iconName:"more",title:"More",className:"more-button",callback(){this.toggleMenu()}},{iconName:"clear",title:"Clear console",callback(){this.clearConsole()}},{iconName:"history",title:`History (${l?"\u2325":"Alt+"}H)`,className:"history-button",callback(){this.toggleHistory()}},{iconName:"horizontalView",title:"Show the editor below the console",callback(){this.setDividerOrient("horizontal")},showIf(){return"horizontal"!==this.dividerOrient}},{iconName:"verticalView",title:"Show the editor beside the console",callback(){this.setDividerOrient("vertical")},showIf(){return"vertical"!==this.dividerOrient}},{iconName:e?"exitFullscreen":"fullscreen",title:e?"Exit full screen":"Full screen",callback(){this.toggleFullscreen()}},{iconName:this.runningCount?"spinner":"play",label:"Run",className:"primary",title:`Run the next block of code (${l?"\u2318":"Ctrl+"}Enter)`,callback(){this.runCode()},disableIf(){return!this.canRunCode}}].filter(e=>!e.showIf||e.showIf.call(this))},historyEntries(){return this.commandHistory.map((e,t)=>{var[i]=parseJSCodeGroups(e),e=(i?.lines??e).split("\n").filter(e=>e.trim());return{index:t,label:i?.headerLines||e[0]||"",detail:e.length+" line"+(1===e.length?"":"s")}}).reverse()},canShrinkText(){return this.textScale>TEXT_SCALES[0]},canGrowText(){return this.textScale<TEXT_SCALES[TEXT_SCALES.length-1]},canRunCode(){return this.jsCode.trim()},mainElemClassNames(){return["vertical"===this.dividerOrient?"col-orient":"row-orient",this.isMovingDivider?"is-moving-divider":""].join(" ")},mainElemStyles(){return{"--divider-size":this.dividerSize,"--editor-pct":this.dividerPct,"--temp-editor-pct":this.tempDividerPct}}},methods:{onEditorKeyCombo(e){(e.ctrlKey||e.metaKey)&&"Enter"===e.key&&this.canRunCode&&this.runCode()},runCode(){this.isDisplaysScrolledToBottom=!0;var[e,...t]=parseJSCodeGroups(this.jsCode),e=(this.runGroup(e),t.map(e=>e.allLines).join("\n"));null!==this.historyIndex?(this.jsCode=[e,this.historyDraft].filter(e=>e.trim()).join("\n"),this.historyIndex=this.historyDraft=null):(this.jsCode=e,this.runCount++)},navigateHistory(e){var t=this.commandHistory;if(e<0)return!!t.length&&(null===this.historyIndex&&(this.historyDraft=this.jsCode,this.historyIndex=t.length),0<this.historyIndex&&this.showHistoryCode(this.historyIndex-1,"start"),!0);if(null===this.historyIndex)return!1;if(this.historyIndex<t.length-1)this.showHistoryCode(this.historyIndex+1,"end");else{const e=this.historyDraft;this.historyIndex=this.historyDraft=null,this.setEditorCode(e,"end")}return!0},showHistoryCode(e,t){null===this.historyIndex&&(this.historyDraft=this.jsCode),this.historyIndex=e,this.setEditorCode(this.commandHistory[e],t)},setEditorCode(e,t){this.jsCode=e,this.$nextTick(()=>{var e=this.$refs.editor?.editor;e&&("end"===t?e.navigateFileEnd():e.navigateFileStart())})},onEditorHistoryKey(e){e.handled=this.navigateHistory(e.direction)},toggleHistory(){this.isHistoryOpen?this.isHistoryOpen=!1:(this.closeMenu(),this.closeValueMenu(),this.isHistoryOpen=!0,this.$nextTick(()=>this.$refs.historyPanel?.querySelector(".menu-item")?.focus()))},recallHistory(e){this.isHistoryOpen=!1,this.showHistoryCode(e,"start"),this.$nextTick(()=>this.$refs.editor?.editor.focus())},stopNavigatingHistory(){this.historyIndex=this.historyDraft=null},runHiddenGroups(){var{hiddenGroups:e}=this;e.length&&e[0].runCount<=this.runCount&&this.runGroup(e.shift())},runGroup(e){var{header:t,isHidden:i}=parseGroupHeader(e.headerLines,this.hidePrefix),t=(this.displays.push({type:"prism",header:t,isHidden:i,isCodeShown:!i,value:e.lines}),this.runningCount++,this.runHistory.push(e.allLines),e.allLines.trim()),{language:t,blockType:r}=(!i&&t&&this.commandHistory[this.commandHistory.length-1]!==t&&(this.commandHistory.push(t),200<this.commandHistory.length)&&this.commandHistory.shift(),this),e="typescript"===t?compileTypeScript(e.lines,{blockType:r}):{code:e.lines},{code:i,resultRange:l}=e.error?{code:"",resultRange:null}:prepareCode(e.code,{blockType:r,importsUrl:this.importsUrl,findResult:this.showResults&&!i});messageParent({target:"runner",func:"runCode",args:[i,{blockType:r,resultRange:l,language:t,sourceMap:e.sourceMap,compileError:e.error}]})},clearConsole(){this.displays=[],messageParent({target:"runner",func:"clearLogs",args:[]})},async resetConsole(){await this.confirm({title:"Reset the console?",message:"The output will be cleared and the editor will go back to the original code."+("window"===this.runnerMode?" Anything the code already defined on the page will stay defined.":""),confirmText:"Reset"})&&this.restart()},restart(){var{visibleCode:e,hiddenGroups:t}=this.originalGroups;this.displays=[],this.jsCode=e,this.hiddenGroups=t.map(e=>({...e})),this.runCount=0,this.runningCount=0,this.runHistory=[],this.stopNavigatingHistory(),messageParent({target:"runner",func:"reset",args:[]}),this.runHiddenGroups()},openFile(){this.closeMenu();var{fileInput:e}=this.$refs;e.value="",e.click()},async onFileChosen(e){var e=e.target.files?.[0],i;e&&(i=unindentMin(await e.text()),(this.displays.length||this.jsCode.trim())&&!await this.confirm({title:`Open ${e.name}?`,message:"The output will be cleared and the code in the editor will be replaced with the code in the file."+("window"===this.runnerMode?" Anything the code already defined on the page will stay defined.":""),confirmText:"Open"})||(this.fileName=e.name,this.originalCode=i,this.restart()))},async saveFile(){this.closeMenu();var e=this.currentCode+"\n",t=this.fileName||(this.isTypeScript?"js-box.ts":"js-box.js"),i=this.isTypeScript?{description:"TypeScript",accept:{"text/typescript":[".ts",".mts"]}}:{description:"JavaScript",accept:{"text/javascript":[".js",".mjs"]}};if("function"==typeof window.showSaveFilePicker)try{const s=await showSaveFilePicker({suggestedName:t,types:[i]}),o=await s.createWritable();return await o.write(e),await o.close(),void(this.fileName=s.name)}catch(e){if("AbortError"===e?.name)return}const s=URL.createObjectURL(new Blob([e],{type:Object.keys(i.accept)[0]}));Object.assign(document.createElement("a"),{href:s,download:t}).click(),setTimeout(()=>URL.revokeObjectURL(s),1e3)},async copyToEditor(e){this.jsCode.trim()&&this.jsCode!==e&&!await this.confirm({title:"Replace the code in the editor?",message:"The code that is currently in the editor will be replaced with a copy of the code you selected.",confirmText:"Replace"})||(this.stopNavigatingHistory(),this.jsCode=e)},confirm(e){return this.dialog?.resolve(!1),new Promise(t=>{this.dialog={...e,resolve:t},this.$nextTick(()=>this.$refs.dialogConfirmButton?.focus())})},openAbout(e){this.aboutTab=e,this.isAboutOpen=!0,this.$nextTick(()=>this.$refs.aboutCloseButton?.focus())},closeAbout(){this.isAboutOpen=!1},async copyExport(){var e=this.exportHtml;try{await navigator.clipboard.writeText(e)}catch(t){var e=Object.assign(document.createElement("textarea"),{value:e});document.body.appendChild(e),e.select(),document.execCommand("copy"),e.remove()}this.copyLabel="Copied!",clearTimeout(this.copyLabelTimeout),this.copyLabelTimeout=setTimeout(()=>this.copyLabel="Copy",1600)},downloadExport(){const e=buildConsoleHtml({code:this.exportJsCode,dataset:this.exportDataset,packageInfo:this.packageInfo,isFullPage:!0}),t=URL.createObjectURL(new Blob([e],{type:"text/html"}));Object.assign(document.createElement("a"),{href:t,download:"js-box.html"}).click(),setTimeout(()=>URL.revokeObjectURL(t),1e3)},onLogRowClick(e,t){e.groupId&&!t.target.closest(".js-value-header.expandable")&&(e.isCollapsed=!e.isCollapsed)},isInCollapsedGroup(e){const{collapsedGroupIds:t}=this;return!!t.size&&!!e.groupIds?.some(e=>t.has(e))},getState(){return JSON.parse(JSON.stringify({displays:this.displays,jsCode:this.jsCode,originalCode:this.originalCode,fileName:this.fileName,commandHistory:this.commandHistory,historyIndex:this.historyIndex,historyDraft:this.historyDraft,runHistory:this.runHistory,hiddenGroups:this.hiddenGroups,runCount:this.runCount,runningCount:this.runningCount,dividerOrient:this.dividerOrient,isDividerOrientAuto:this.isDividerOrientAuto,dividerPct:this.dividerPct}))},restoreState(e){Object.assign(this,e),this.isDisplaysScrolledToBottom=!0},toggleMenu(){this.isMenuOpen?this.closeMenu():(this.isHistoryOpen=!1,this.closeValueMenu(),this.isMenuOpen=!0,this.$nextTick(()=>this.$refs.moreMenu?.querySelector(".menu-item:not(:disabled)")?.focus()))},closeMenu(e){this.isMenuOpen=!1,e&&document.querySelector("#bottomNav .more-button")?.focus()},onMenuKeyDown(e){var t,i,s;"Escape"===e.key?(e.stopPropagation(),this.closeMenu(this.isMenuOpen),this.closeValueMenu(),this.isHistoryOpen=!1):"ArrowDown"!==e.key&&"ArrowUp"!==e.key||(e.preventDefault(),i=(t=[...e.currentTarget.querySelectorAll(".menu-item:not(:disabled)")]).indexOf(document.activeElement),t[(i+("ArrowDown"===e.key?1:t.length-1))%t.length]?.focus())},changeTextScale(e){var e=TEXT_SCALES.indexOf(this.textScale)+e;0<=e&&e<TEXT_SCALES.length&&this.setTextScale(TEXT_SCALES[e])},setTextScale(e){this.textScale=e;try{localStorage.setItem("yourjs-box.textScale",""+e)}catch(e){}},async toggleFullscreen(){if(this.isMaximized)this.setMaximized(!1);else if(document.fullscreenElement)await document.exitFullscreen();else try{await document.documentElement.requestFullscreen()}catch(e){this.isPopOut||this.setMaximized(!0)}},setMaximized(e){this.isMaximized=e,messageParent({target:"host",func:"setMaximized",args:[e]})},popOut(){this.closeMenu(),this.isMaximized&&this.setMaximized(!1),messageParent({target:"host",func:"popOut",args:[this.getState()]})},bringBack(){this.hasSentState=!0;var e=window.yourjsBoxPopIn;"function"==typeof e?e(this.getState()):messageParent({target:"host",func:"popIn",args:[this.getState()]})},focusPopOut(){messageParent({target:"host",func:"focusPopOut",args:[]})},requestPopIn(){messageParent({target:"host",func:"requestPopIn",args:[]})},onWindowMouseDown(e){this.isMenuOpen&&!e.target.closest(".more-menu, .more-button")&&this.closeMenu(),this.valueMenu&&!e.target.closest(".value-menu")&&this.closeValueMenu(),this.isHistoryOpen&&!e.target.closest(".history-panel, .history-button")&&(this.isHistoryOpen=!1)},onWindowKeyDown(e){!e.altKey||e.ctrlKey||e.metaKey||"KeyH"!==e.code?"Escape"===e.key&&this.valueMenu?this.closeValueMenu():"Escape"!==e.key||!this.isMaximized||this.isMenuOpen||this.dialog||this.isAboutOpen||this.setMaximized(!1):(e.preventDefault(),e.stopPropagation(),this.toggleHistory())},openValueMenu(e,{path:t,keyPath:i,isPrimitive:s}){this.closeMenu(),this.valueMenu={x:e.clientX,y:e.clientY,path:t.slice(),propertyPath:i?.length?formatPropertyPath(i):null,fileName:i?.length&&/^[\w$-]+$/.test(i[i.length-1])?i[i.length-1]:"value",isPrimitive:s},this.$nextTick(()=>{var e=this.$refs.valueMenu,t,i;e&&this.valueMenu&&({width:t,height:i}=e.getBoundingClientRect(),this.valueMenu.x=Math.max(4,Math.min(this.valueMenu.x,innerWidth-t-4)),this.valueMenu.y=Math.max(4,Math.min(this.valueMenu.y,innerHeight-i-4)),e.querySelector(".menu-item")?.focus())})},closeValueMenu(){this.valueMenu=null},requestValueJson(e){const t=Date.now()+"-"+Math.random();return new Promise(i=>{jsonRequests.set(t,i),messageParent({target:"runner",func:"getValueAsJson",args:[e,t]})})},showToast(e){clearTimeout(this.toastTimeout),this.toast={message:e},this.toastTimeout=setTimeout(()=>this.toast=null,3500)},showJsonToast({circularCount:e,error:t},i){this.showToast(t||i+(e?` (${e} circular reference${1===e?" was":"s were"} left out)`:""))},async copyValueAsJson(){const e=[...this.valueMenu.path];this.closeValueMenu();var t=this.requestValueJson(e);try{if(window.ClipboardItem&&navigator.clipboard?.write)await navigator.clipboard.write([new ClipboardItem({"text/plain":t.then(({json:e,error:t})=>{if(t)throw new Error(t);return new Blob([e],{type:"text/plain"})})})]);else{const{json:e,error:i}=await t;if(i)throw new Error(i);await navigator.clipboard.writeText(e)}this.showJsonToast(await t,"Copied as JSON")}catch(e){var t=await t;this.showToast(t.error||"The value couldn't be copied. Your browser may not allow copying here.")}},async saveValueAsJson(){const{fileName:e}=this.valueMenu,t=[...this.valueMenu.path];this.closeValueMenu();var i=this.requestValueJson(t),s=e+".json";let o;if("function"==typeof window.showSaveFilePicker)try{o=await showSaveFilePicker({suggestedName:s,types:[{description:"JSON",accept:{"application/json":[".json"]}}]})}catch(e){if("AbortError"===e?.name)return}var i=await i;if(i.error)this.showToast(i.error);else{var n=i.json+"\n";if(o){const e=await o.createWritable();await e.write(n),await e.close()}else{const e=URL.createObjectURL(new Blob([n],{type:"application/json"}));Object.assign(document.createElement("a"),{href:e,download:s}).click(),setTimeout(()=>URL.revokeObjectURL(e),1e3)}this.showJsonToast(i,"Saved as JSON")}},storeValueAsGlobal(){var e=[...this.valueMenu.path];this.closeValueMenu(),messageParent({target:"runner",func:"storeAsGlobal",args:[e]})},async copyPropertyPath(){var{propertyPath:e}=this.valueMenu;this.closeValueMenu();try{await navigator.clipboard.writeText(e),this.showToast("Copied "+e)}catch(e){this.showToast("The property path couldn't be copied. Your browser may not allow copying here.")}},refreshValue(){var e=[...this.valueMenu.path];this.closeValueMenu(),messageParent({target:"runner",func:"refreshDescription",args:[e]})},closeDialog(e){var{dialog:t}=this;this.dialog=null,t?.resolve(e)},setDividerOrient(e){this.isDividerOrientAuto=!1,this.dividerOrient=e},onWindowResize(){this.isDividerOrientAuto&&(this.dividerOrient=getAutoDividerOrient())},onDisplaysScroll(){this.closeValueMenu();var{scrollTop:e,scrollHeight:t,clientHeight:i}=this.$refs.displaysScroller;this.isDisplaysScrolledToBottom=t-e-i<8},getEditorPct(e){var t=this.$refs.main.getBoundingClientRect(),{dividerOrient:i}=this,s=e.pageX-t.left,e=e.pageY-t.top,r=t.width,t=t.height;return 100-100*Math.min(Math.max(.2,"vertical"===i?s/r:e/t),.8)+"%"},onMainElemMouseDown(e){e.target===this.$refs.mainDivider&&(this.isMovingDivider=!0,this.tempDividerPct=this.getEditorPct(e))},onWindowMouseMove(e){this.isMovingDivider&&(this.tempDividerPct=this.getEditorPct(e))},onWindowMouseUp(e){this.isMovingDivider&&(this.isMovingDivider=!1,this.dividerPct=this.getEditorPct(e))},onWindowError(e){this.displays.push({type:"error",message:e.error?.stack??e.message??e.error?.message??""+e.error,line:e.lineno,column:e.colno})}},watch:{textScale:{handler(e){document.documentElement.style.setProperty("--text-scale",e)},immediate:!0},theme:{handler(e){document.documentElement.dataset.theme=e},immediate:!0},"displays.length"(){this.isDisplaysScrolledToBottom&&this.$nextTick(()=>{var e=this.$refs.displaysScroller;e.scrollTop=e.scrollHeight})}},mounted(){addEventListener("mousemove",this.onWindowMouseMove),addEventListener("mousedown",this.onWindowMouseDown),addEventListener("keydown",this.onWindowKeyDown,!0),addEventListener("resize",this.onWindowResize),addEventListener("mouseup",this.onWindowMouseUp),addEventListener("error",this.onWindowError),o.addEventListener("change",e=>this.prefersDark=e.matches),document.addEventListener("fullscreenchange",()=>this.isFullscreen=!!document.fullscreenElement),this.isPopOut&&addEventListener("pagehide",()=>this.hasSentState||this.bringBack()),this.runningCount||this.runHiddenGroups(),setTimeout(()=>document.querySelector("#splash").classList.add("hidden"),Math.max(0,(this.isPopOut?0:1e3)-performance.now()))}}).component("ace-editor",getAceComponentProps()).component("prism",getPrismComponentProps()).component("icon",getIconComponentProps()).component("js-value",getJSValueComponentProps()).mount(document.querySelector("#vueApp"))}}function getAceComponentProps(){return{data:()=>({annotations:[]}),props:["fontSize","height","keybinding","language","modelValue","readOnly","theme","width"],computed:{infoNotes(){return this.annotations.filter(({type:e})=>"info"===e)},warningNotes(){return this.annotations.filter(({type:e})=>"warning"===e)},errorNotes(){return this.annotations.filter(({type:e})=>"error"===e)},style(){return{height:null!=this.height?"number"==typeof this.height?this.height+"px":this.height:"150px",width:null!=this.width?"number"==typeof this.width?this.width+"px":this.width:"100%"}},modeSig(){return"ace/mode/"+(this.language??"text")},themeSig(){return"ace/theme/"+(""+(this.theme??"light")).replace(/^light$|(^dark$)/i,(e,t)=>"cloud_editor"+(t?"_dark":""))}},watch:{themeSig(e){this.editor.setTheme(e)},fontSize(e){e&&this.editor.setFontSize(e)},modelValue(e){e!==this.editor.getValue()&&this.editor.setValue(e,-1)}},async mounted(){const e=ace.edit(this.$refs.editor,{value:this.modelValue,mode:this.modeSig,theme:this.themeSig});this.editor=e,this.fontSize&&e.setFontSize(this.fontSize),this.readOnly&&(e.setReadOnly(!0),e.setHighlightActiveLine(!1),e.session.setUseWorker(!1)),e.setKeyboardHandler("ace/keyboard/vscode"),e.commands.removeCommand("addLineAfter"),e.commands.removeCommand("addLineBefore"),e.on("change",()=>this.$emit("update:modelValue",e.getValue())),e.session.on("changeAnnotation",()=>{var t=JSON.stringify(this.errorNotes),i=JSON.stringify(this.infoNotes),s=JSON.stringify(this.warningNotes),{errorNotes:o,infoNotes:r,warningNotes:n}=(this.annotations=e.getSession().getAnnotations(),this);t!==JSON.stringify(o)&&this.$emit("changeErrorNotes",o),i!==JSON.stringify(r)&&this.$emit("changeInfoNotes",r),s!==JSON.stringify(n)&&this.$emit("changeWarningNotes",n)}),this.$refs.editor.addEventListener("keydown",t=>{var i="ArrowUp"===t.key,s,o,r,s;!i&&"ArrowDown"!==t.key||t.shiftKey||t.altKey||t.ctrlKey||t.metaKey||!e.selection.isEmpty()||({row:s,column:o}=e.getCursorPosition(),r=e.session.getLength()-1,(i?0===s&&0===o:s===r&&o===e.session.getLine(r).length)&&(this.$emit("historyKey",s={direction:i?-1:1,handled:!1}),s.handled)&&(t.preventDefault(),t.stopPropagation()))},!0),e.textInput.getElement().addEventListener("keydown",e=>{16!==e.keyCode&&17!==e.keyCode&&18!==e.keyCode&&91!==e.keyCode&&92!==e.keyCode&&93!==e.keyCode&&(e.metaKey||e.ctrlKey||e.altKey||e.shiftKey&&1<(e.key??"").length)&&this.$emit("keyCombo",e)})},template:'<div ref="editor" :style="style"></div>'}}function getPrismComponentProps(){return{data:()=>({annotations:[]}),props:["code","isDark","language","lineNumbers","matchBraces"],computed:{html(){},preStyle(){return{filter:!1!==(this.isDark??!1)?"none":"invert(1) hue-rotate(180deg) brightness(1.1)",margin:0,paddingTop:"0.5em",paddingBottom:"0.5em"}}},watch:{code(){this.redraw()},language(){this.redraw()},lineNumbers(){this.redraw()},matchBraces(){this.redraw()}},methods:{async redraw(){const e=this.$refs.pre,t=this.$refs.code;t.textContent=this.code,t.className="language-"+(this.language??"javascript"),e.className="";for(const t of["lineNumbers","matchBraces"]){var i;null!=this[t]&&(i=t.replace(/[A-Z]+/g,"-$&").toLowerCase(),e.className+=" "+i)}Prism.highlightElement(t)}},async mounted(){await this.redraw()},template:'<pre ref="pre" :style="preStyle"><code ref="code"></code></pre>'}}function getIconComponentProps(){return{props:["name"],computed:{svgCode(){var e={missing:'<svg viewBox="0 0 32 32"><circle cx="16" cy="22.5" r="1.5" fill="currentColor"/><path fill="currentColor" d="M17 19h-2v-4h2c1.103 0 2-.897 2-2s-.897-2-2-2h-2c-1.103 0-2 .897-2 2v.5h-2V13c0-2.206 1.794-4 4-4h2c2.206 0 4 1.794 4 4s-1.794 4-4 4z"/><path fill="currentColor" d="M29.391 14.527L17.473 2.609A2.078 2.078 0 0 0 16 2c-.533 0-1.067.203-1.473.609L2.609 14.527C2.203 14.933 2 15.466 2 16s.203 1.067.609 1.473L14.526 29.39c.407.407.941.61 1.474.61s1.067-.203 1.473-.609L29.39 17.474c.407-.407.61-.94.61-1.474s-.203-1.067-.609-1.473M16 28.036L3.965 16L16 3.964L28.036 16z"/></svg>',trash:'<svg viewBox="0 0 15 15"><path fill="currentColor" fill-rule="evenodd" d="M5.5 1a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1zM3 3.5a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 0 1H11v8a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V4h-.5a.5.5 0 0 1-.5-.5M5 4h5v8H5z" clip-rule="evenodd"/></svg>',play:'<svg viewBox="0 0 16 16"><path fill="currentColor" d="M2 1v14l12-7z"/></svg>',refresh:'<svg viewBox="0 0 15 15"><path fill="currentColor" fill-rule="evenodd" d="M1.903 7.297c0 3.044 2.207 5.118 4.686 5.547a.521.521 0 1 1-.178 1.027C3.5 13.367.861 10.913.861 7.297c0-1.537.699-2.745 1.515-3.663c.585-.658 1.254-1.193 1.792-1.602H2.532a.5.5 0 0 1 0-1h3a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-1 0V2.686l-.001.002c-.572.43-1.27.957-1.875 1.638c-.715.804-1.253 1.776-1.253 2.97m11.108.406c0-3.012-2.16-5.073-4.607-5.533a.521.521 0 1 1 .192-1.024c2.874.54 5.457 2.98 5.457 6.557c0 1.537-.699 2.744-1.515 3.663c-.585.658-1.254 1.193-1.792 1.602h1.636a.5.5 0 1 1 0 1h-3a.5.5 0 0 1-.5-.5v-3a.5.5 0 1 1 1 0v1.845h.002c.571-.432 1.27-.958 1.874-1.64c.715-.803 1.253-1.775 1.253-2.97" clip-rule="evenodd"/></svg>',horizontalView:'<svg viewBox="0 0 15 15"><path fill="currentColor" fill-rule="evenodd" d="M1.5 2h12a.5.5 0 0 1 .5.5V7H1V2.5a.5.5 0 0 1 .5-.5M1 8v4.5a.5.5 0 0 0 .5.5h12a.5.5 0 0 0 .5-.5V8zM0 2.5A1.5 1.5 0 0 1 1.5 1h12A1.5 1.5 0 0 1 15 2.5v10a1.5 1.5 0 0 1-1.5 1.5h-12A1.5 1.5 0 0 1 0 12.5z" clip-rule="evenodd"/></svg>',verticalView:'<svg viewBox="0 0 15 15"><path fill="currentColor" fill-rule="evenodd" d="M8 2h5.5a.5.5 0 0 1 .5.5v10a.5.5 0 0 1-.5.5H8zM7 2H1.5a.5.5 0 0 0-.5.5v10a.5.5 0 0 0 .5.5H7zm-7 .5A1.5 1.5 0 0 1 1.5 1h12A1.5 1.5 0 0 1 15 2.5v10a1.5 1.5 0 0 1-1.5 1.5h-12A1.5 1.5 0 0 1 0 12.5z" clip-rule="evenodd"/></svg>',error:'<svg viewBox="0 0 24 24"><path fill="currentColor" d="M11 15h2v2h-2zm0-8h2v6h-2zm1-5C6.47 2 2 6.5 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 18a8 8 0 0 1-8-8a8 8 0 0 1 8-8a8 8 0 0 1 8 8a8 8 0 0 1-8 8"/></svg>',history:'<svg viewBox="0 0 16 16"><path d="M2.5 8a5.5 5.5 0 1 0 1.6-3.9" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><path d="M2.25 2.5v2.75H5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M8 5v3.25l2.25 1.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',copy:'<svg viewBox="0 0 16 16"><rect x="5.5" y="5.5" width="8" height="8" rx="1.25" fill="none" stroke="currentColor" stroke-width="1.4"/><path d="M10.5 3.5v-.75A1.25 1.25 0 0 0 9.25 1.5h-5A1.25 1.25 0 0 0 3 2.75v5A1.25 1.25 0 0 0 4.25 9h.75" fill="none" stroke="currentColor" stroke-width="1.4"/></svg>',variable:'<svg viewBox="0 0 16 16"><path d="M5 2.5c-1.5 1.5-2 3.5-2 5.5s.5 4 2 5.5M11 2.5c1.5 1.5 2 3.5 2 5.5s-.5 4-2 5.5M6.5 6l3 4M9.5 6l-3 4" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>',path:'<svg viewBox="0 0 16 16"><circle cx="3.5" cy="12.5" r="1.5" fill="currentColor"/><circle cx="12.5" cy="3.5" r="1.5" fill="currentColor"/><path d="M3.5 11V8a2 2 0 0 1 2-2h5a2 2 0 0 0 2-2" fill="none" stroke="currentColor" stroke-width="1.4"/></svg>',open:'<svg viewBox="0 0 16 16"><path d="M2 4.5a1 1 0 0 1 1-1h3.2l1.3 1.5H13a1 1 0 0 1 1 1V12a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/></svg>',save:'<svg viewBox="0 0 16 16"><path d="M8 2.5v7M5 7l3 3 3-3M3 11.5v1.5h10v-1.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',fullscreen:'<svg viewBox="0 0 16 16"><path d="M2.5 6V2.5H6M10 2.5h3.5V6M13.5 10v3.5H10M6 13.5H2.5V10" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',exitFullscreen:'<svg viewBox="0 0 16 16"><path d="M6 2.5V6H2.5M13.5 6H10V2.5M10 13.5V10h3.5M2.5 10H6v3.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',more:'<svg viewBox="0 0 16 16"><circle cx="3.5" cy="8" r="1.4" fill="currentColor"/><circle cx="8" cy="8" r="1.4" fill="currentColor"/><circle cx="12.5" cy="8" r="1.4" fill="currentColor"/></svg>',popOut:'<svg viewBox="0 0 16 16"><path d="M9.5 2.5h4v4M13.5 2.5L8 8M12 9.5v3a1 1 0 0 1-1 1H3.5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h3" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',popIn:'<svg viewBox="0 0 16 16"><path d="M12 8.5H8V4.5M8 8.5l5.5-5.5M12 10.5v2a1 1 0 0 1-1 1H3.5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h2" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',code:'<svg viewBox="0 0 16 16"><path d="M5.5 4.5L2 8l3.5 3.5M10.5 4.5L14 8l-3.5 3.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',info:'<svg viewBox="0 0 16 16"><circle cx="8" cy="8" r="6.25" fill="none" stroke="currentColor" stroke-width="1.5"/><path d="M8 7.25v4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="8" cy="5" r="1" fill="currentColor"/></svg>',result:'<svg viewBox="0 0 16 16"><path d="M9 4.5L5.5 8 9 11.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><circle cx="12" cy="8" r="1.1" fill="currentColor"/></svg>',close:'<svg viewBox="0 0 16 16"><path d="M4 4l8 8m0-8l-8 8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>',clear:'<svg viewBox="0 0 16 16"><circle cx="8" cy="8" r="6" fill="none" stroke="currentColor" stroke-width="1.5"/><path d="M3.75 12.25l8.5-8.5" stroke="currentColor" stroke-width="1.5"/></svg>',copyToEditor:'<svg viewBox="0 0 16 16"><path d="M6 3.5L2.5 7 6 10.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 7h6.5a4 4 0 0 1 4 4v1.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>',spinner:'<svg viewBox="0 0 16 16" class="spin"><path d="M8 1.75a6.25 6.25 0 1 1-6.25 6.25" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round"/></svg>',chevron:'<svg viewBox="0 0 16 16"><path d="M6 4l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',consoleError:'<svg viewBox="0 0 16 16"><circle cx="8" cy="8" r="7" fill="currentColor"/><path d="M5.5 5.5l5 5m0-5l-5 5" stroke="#fff" stroke-width="1.75" stroke-linecap="round"/></svg>',consoleWarning:'<svg viewBox="0 0 16 16"><path d="M8 1.75L14.75 14H1.25z" fill="currentColor" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M8 6v3.5" stroke="#202124" stroke-width="1.75" stroke-linecap="round"/><circle cx="8" cy="11.75" r="1" fill="#202124"/></svg>'};return(e[this.name]??e.missing).replace("<svg",'$& xmlns="http://www.w3.org/2000/svg" style="height: 1em; width: 1em; display: inline-block; transform: translateY(0.1em);"')}},template:'<span v-html="svgCode"></span>'}}function getJSValueComponentProps(){return{props:["description","path","name","isDimName","keyPath"],data:()=>({isExpanded:!1,hasBeenExpanded:!1}),watch:{isExpanded(e){e&&!this.hasBeenExpanded&&(this.hasBeenExpanded=e)},isPartialDescription(e){e&&this.isExpanded&&this.requestDescription()}},computed:{isPartialDescription(){return void 0===this.description.entries},isExpandable(){return!this.description.isPrimitive},isEntry(){return null!=this.name},classNames(){return["js-value",this.isEntry||this.isExpandable&&this.isExpanded?"d-block":"d-inline-block",this.isExpanded?"expanded":""]},entryGroups(){const{keyPath:e,description:t}=this;return[{key:"entries",isDim:e=>!1===e[2],getKeyPath:i=>e&&t.entriesArePropertyKeys?e.concat([i[0]]):null},{key:"protoEntries",isDim:()=>!0,getKeyPath:()=>e}]}},methods:{toggleExpanded(){this.isExpandable&&(this.isExpanded=!this.isExpanded,this.isExpanded)&&this.isPartialDescription&&this.requestDescription()},requestDescription(){messageParent({target:"runner",func:"sendDescriptionFor",args:[this.path]})},openMenu(e){this.$root.openValueMenu(e,{path:this.path,keyPath:this.keyPath,isPrimitive:this.description.isPrimitive})}},template:'\n <div :class="classNames">\n <div :class="[\'js-value-header\', isExpandable ? \'expandable\' : \'\']" @click="toggleExpanded" @contextmenu.prevent.stop="openMenu"><span\n v-if="isExpandable || isEntry" :class="[\'arrow\', isExpandable ? \'expandable\' : \'\', isExpanded ? \'expanded\' : \'\']"></span><template\n v-if="isEntry"><span :class="[\'entry-key\', isDimName ? \'dim\' : \'\']">{{ name }}</span>: </template><span\n v-for="part in description.parts" :class="\'t-\' + part[0]">{{ part[1] }}</span></div>\n <div v-if="hasBeenExpanded" v-show="isExpanded" class="expansion">\n <div v-if="isPartialDescription" class="loading">Loading&hellip;</div>\n <template v-else>\n <template v-for="group in entryGroups">\n <js-value\n v-for="(entry, entryIndex) in description[group.key]"\n :name="entry[0]"\n :is-dim-name="group.isDim(entry)"\n :description="entry[1]"\n :key-path="group.getKeyPath(entry)"\n :path="path.concat([group.key, entryIndex])">\n </js-value>\n </template>\n </template>\n </div>\n </div>\n '}}function parseJSCodeGroups(e){return e.split(/\r\n|\r|\n/).reduce((e,t)=>{var i=e[e.length-1],s=/^\/\/[^]*\\\\$/.test(t),o=s?t.replace(/^\/+\s*|\s*\\+$/g,""):t;return!e.length||s&&!i.canAppendHeader?e.push({headerLines:s?[o]:[],lines:s?[]:[t],allLines:[t],canAppendHeader:s}):(s?i.headerLines.push(o):(i.canAppendHeader=!1,i.lines.push(t)),i.allLines.push(t)),e},[]).reduce((e,t)=>(t.canAppendHeader||(delete t.canAppendHeader,t.headerLines=t.headerLines.join("\n").trimEnd(),t.lines=t.lines.join("\n"),t.allLines=t.allLines.join("\n"),e.push(t)),e),[])}function parseGroupHeader(e,t){var i=!!t&&e.startsWith(t);return{header:i?e.slice(t.length).replace(/^\s*:?\s*/,""):e,isHidden:i}}function extractHiddenGroups(e,t){var i=[],s=[];for(const o of parseJSCodeGroups(e))parseGroupHeader(o.headerLines,t).isHidden?s.push({...o,runCount:i.length}):i.push(o);return{visibleCode:i.map(e=>e.allLines).join("\n"),hiddenGroups:s}}function compileTypeScript(e,{blockType:t}){try{var i=Babel.transform(e,{filename:"snippet.ts",presets:[["typescript",{allExtensions:!0,onlyRemoveTypeImports:!0}]],sourceType:"module"===t?"module":"script",parserOpts:{allowImportExportEverywhere:"module"!==t},retainLines:!0,sourceMaps:!0});return{code:i.code,sourceMap:decodeSourceMap(i.map.mappings)}}catch(t){if("SyntaxError"===t?.name&&t.loc)return{code:e,error:{message:(""+t.message).split("\n")[0].replace(/^\/?snippet\.ts:\s*/,"").replace(/\s*\(\d+:\d+\)$/,""),line:t.loc.line,column:t.loc.column+1}};throw t}}function decodeSourceMap(e){const t=[0,0,0,0,0];return e.split(";").map(e=>{t[0]=0;const i=[];for(const s of e.split(","))if(s){const e=[];let o=0,r=0;for(const t of s){const i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(t);o+=(31&i)<<r,32&i?r+=5:(e.push(1&o?-(o>>>1):o>>>1),o=r=0)}e.forEach((e,i)=>t[i]+=e),4<=e.length&&i.push([t[0],t[2],t[3]])}return i.sort((e,t)=>e[0]-t[0])})}function prepareCode(e,{blockType:t,importsUrl:i,findResult:s}){if(!window.acorn)return{code:e,resultRange:null};let o;try{o=acorn.parse(e,{ecmaVersion:"latest",sourceType:"module"===t?"module":"script",allowHashBang:!0})}catch(t){return{code:e,resultRange:null}}let r=null;if(s){const e=o.body[o.body.length-1];"ExpressionStatement"!==e?.type||e.directive||(r=[e.expression.start,e.expression.end])}const n=[];i&&walkAst(o,e=>{var{source:e}=/^(Import(Declaration|Expression)|Export(All|Named)Declaration)$/.test(e.type)?e:{};"Literal"===e?.type&&"string"==typeof e.value&&isBareSpecifier(e.value)&&n.push({start:e.start,end:e.end,text:JSON.stringify(i.replace(/\{specifier\}/g,e.value))})}),n.sort((e,t)=>t.start-e.start);for(const{start:t,end:i,text:s}of n){e=e.slice(0,t)+s+e.slice(i);const o=s.length-(i-t);r=r&&r.map(e=>e>=i?e+o:e)}return{code:e,resultRange:r}}function formatPropertyPath(e){return e.map((e,t)=>/^(0|[1-9]\d*)$/.test(e)?`[${e}]`:/^[A-Za-z_$][\w$]*$/.test(e)?(t?".":"")+e:`[${JSON.stringify(e)}]`).join("")}function isBareSpecifier(e){return!/^(\.{0,2}\/|#|[a-z][a-z\d+.-]*:)/i.test(e)}function walkAst(e,t){if(Array.isArray(e))for(const i of e)walkAst(i,t);else if(e&&"string"==typeof e.type){t(e);for(const i of Object.keys(e)){var s=e[i];s&&"object"==typeof s&&walkAst(s,t)}}}function joinCodeBlocks(e){return e.map(e=>e.replace(/^(\s*[\r\n])+|\s+$/g,"")).filter(Boolean).map((e,t)=>{var i=e.split(/\r\n|\r|\n/)[0];return t&&!/^\/\/[^]*\\\\$/.test(i)?`// \\\\
5
+ at ${d}:${+t}:`+ +n})}else if("module"===o)await import("data:text/javascript;charset=utf-8,"+encodeURIComponent(r));else if("worker"===n)J(r);else{const e=document.createElement("script");e.textContent=r,document.head.appendChild(e),e.remove()}}catch(e){O(e)}a=void 0,e({target:"viewer",func:"onCodeRan",args:[]})}function J(e){if(c)try{return importScripts("data:text/javascript;charset=utf-8,"+encodeURIComponent(e))}catch(e){if("NetworkError"!==e?.name)throw e;c=!1}var t=URL.createObjectURL(new Blob([e],{type:"text/javascript"}));try{importScripts(t)}finally{URL.revokeObjectURL(t)}}function V(e){F(e,!1)}function z(e){F(e,!0)}function F(t,n){var r=B(t),o,n;r&&(o=P(r.value,"receiver"in r?r.receiver:r.value),Object.assign(r,o),n=n?C(r.value,2<t.length?1:0,"protoEntries"===t[t.length-2]):{},e({target:"viewer",func:"updateDescriptionFor",args:[t,{...S(["$entries","$protoEntries"],o),...n}]}))}function B(e){let t=o;return e.forEach((e,n)=>{t=t?.[n&&n%2==0?"$"+e:e]}),t}function G(t,n){var t=B(t);let o;try{o=t?_(t.value):{error:"The value is no longer available."}}catch(e){o={error:`The value couldn't be converted to JSON (${e?.message??e}).`}}e({target:"viewer",func:"onValueJson",args:[{requestId:n,...o}]})}function _(e){let t=0;const n=[],r=JSON.stringify(e,function(e,r){for(;n.length&&n[n.length-1].converted!==this;)n.pop();if("bigint"==typeof r)return""+r;if(null!==r&&"object"==typeof r){const e=r;if(n.some(t=>t.original===e))return void t++;(r instanceof Map||r instanceof Set)&&(r=[...r]),n.push({original:e,converted:r})}return r},2);return void 0===r?{error:"This value can't be represented as JSON.",circularCount:t}:{json:r,circularCount:t}}function q(t){var t=B(t);if(t){let r=1;for(;"temp"+r in globalThis;)r++;globalThis["temp"+r]=t.value,e({target:"viewer",func:"onStoredAsGlobal",args:["temp"+r]})}}function K(){for(const e of Object.keys(o))delete o[e];d=[]}return{clearLogs:K,destroy:j,getValueAsJson:G,refreshDescription:z,runCode:I,sendDescriptionFor:V,storeAsGlobal:q}}function createWorkerRunner(onMessage){const WORKER_SOURCE="(function(){var runner = ("+createRunner+')(function(m) { postMessage(m); }, {mode: "worker"});onmessage = function(e) {var d = e.data;if (d && Object.prototype.hasOwnProperty.call(runner, d.func) && Array.isArray(d.args)) {runner[d.func].apply(null, d.args);}};postMessage({target: "main", func: "ready"});})();';let canUseDataUrl=!0,blobUrl,worker,isReady,pendingMessages;function start(){isReady=!1,pendingMessages=[];var url=canUseDataUrl?"data:text/javascript;charset=utf-8,"+encodeURIComponent(WORKER_SOURCE):blobUrl??=URL.createObjectURL(new Blob([WORKER_SOURCE],{type:"text/javascript"}));try{worker=new Worker(url)}catch(e){if(canUseDataUrl)return canUseDataUrl=!1,start();throw e}const thisWorker=worker;worker.onmessage=e=>{if(thisWorker===worker)if("main"===e.data?.target&&"ready"===e.data.func){isReady=!0;for(const message of pendingMessages.splice(0))worker.postMessage(message)}else onMessage(e.data)},worker.onerror=e=>{var e;thisWorker===worker&&!isReady&&canUseDataUrl&&(e.preventDefault(),canUseDataUrl=!1,e=pendingMessages,worker.terminate(),start(),pendingMessages.push(...e))}}return start(),{destroy(){worker.terminate(),blobUrl&&URL.revokeObjectURL(blobUrl)},apply(func,args){"reset"===func?(worker.terminate(),start()):isReady?worker.postMessage({func:func,args:args}):pendingMessages.push({func:func,args:args})}}}function createWindowRunner(onMessage){const runner=createRunner(onMessage,{mode:"window",ownUrl:OWN_URL});return{destroy(){runner.destroy()},apply(func,args){"reset"===func?runner.clearLogs():runner[func](...args)}}}function createConsole({code,dataset,height,insert}){const runnerMode="window"===dataset.runner?"window":"worker",blockType="module"===dataset.blockType?"module":"classic",language="typescript"===dataset.language?"typescript":"javascript",showResults="false"!==dataset.showResults,importsUrl=null==dataset.importsUrl?DEFAULT_IMPORTS_URL:dataset.importsUrl&&resolveUrlTemplate(dataset.importsUrl),libraryUrl=getLibraryFileUrl.bind(null,dataset.librariesUrl||DEFAULT_LIBRARIES_URL);let inlineViewer,popOutViewer=null,popOutWindow=null,popOutWatcher,activeViewer;const sendToViewer=data=>relayMessage(data,{viewer:activeViewer});let runner=null;const theme=/^(light|dark)$/.test(dataset.theme)?dataset.theme:matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light",hostFuncs={setMaximized(isMaximized){var{style}=inlineViewer.iframe;isMaximized?(inlineViewer.normalCssText??=style.cssText,Object.assign(style,{position:"fixed",inset:"0",width:"100%",height:"100%",zIndex:"2147483647"})):null!=inlineViewer.normalCssText&&(style.cssText=inlineViewer.normalCssText,inlineViewer.normalCssText=null)},popOut(state){if(popOutWindow)popOutWindow.focus();else{var rect=inlineViewer.iframe.getBoundingClientRect(),width=Math.max(820,Math.round(rect.width)),rect=Math.max(560,Math.round(rect.height));const newWindow=open("","_blank",`popup,width=${width},height=`+rect);newWindow?(popOutWindow=newWindow,popOutViewer=createViewer(newWindow,state),newWindow.yourjsBoxPopIn=state=>newWindow===popOutWindow&&hostFuncs.popIn(state),activeViewer=popOutViewer,inlineViewer.call("setPoppedOut",!0),popOutWatcher=setInterval(()=>{newWindow.closed&&setTimeout(()=>newWindow===popOutWindow&&hostFuncs.popIn(null),300)},500)):inlineViewer.call("onPopOutFailed")}},popIn(state){var oldWindow=popOutWindow;oldWindow&&(clearInterval(popOutWatcher),popOutWindow=null,popOutViewer.dispose(),popOutViewer=null,(activeViewer=inlineViewer).call("setPoppedOut",!1,state),oldWindow.closed||oldWindow.close())},requestPopIn(){popOutViewer&&popOutViewer.call("popIn")},focusPopOut(){popOutWindow?.focus()}},closePopOut=()=>popOutWindow?.close();function createViewer(targetWindow,state){return createCallableFrame({deferLoad:!targetWindow,jsCode(){let mountedApp;const IS_MISSING_LIBRARIES=!window.Vue||!window.ace||!window.Prism,Prism=(IS_MISSING_LIBRARIES&&document.querySelector("#splash").classList.add("failed"),window.Prism),MIN_LOADING_TIME=(delete window.Prism,Prism?.plugins.autoloader.loadLanguages("javascript"),1e3),POP_IN_FUNCTION_NAME="yourjsBoxPopIn",TEXT_SCALES=[.75,.9,1,1.15,1.3,1.5,1.75,2],TEXT_SCALE_STORAGE_KEY="yourjs-box.textScale";function loadTextScale(){try{var e=+localStorage.getItem("yourjs-box.textScale");return TEXT_SCALES.includes(e)?e:1}catch(e){return 1}}const NARROW_WIDTH=600;function getAutoDividerOrient(){return innerWidth<600?"horizontal":"vertical"}function init(e,t,i){if(!IS_MISSING_LIBRARIES){if("typescript"===i.language&&!window.Babel)return document.querySelector("#splash").classList.add("failed");Prism.plugins.autoloader.loadLanguages(i.language);const s=t.hidePrefix??"",o=matchMedia("(prefers-color-scheme: dark)"),r=unindentMin(e),{visibleCode:n,hiddenGroups:a}=extractHiddenGroups(r,s),l=/Mac|iPhone|iPad/.test(navigator.platform);mountedApp=Vue.createApp({data:()=>({displays:[],hidePrefix:s,hiddenGroups:a.map(e=>({...e})),runnerMode:i.runnerMode,importsUrl:i.importsUrl,originalCode:r,fileName:null,blockType:i.blockType,language:i.language,showResults:i.showResults,packageInfo:i.packageInfo,libraryVersions:i.libraryVersions,runHistory:[],isAboutOpen:!1,aboutTab:"about",exportCode:"current",exportFormat:"snippet",copyLabel:"Copy",runningCount:0,dialog:null,isDisplaysScrolledToBottom:!0,forcedTheme:/^(light|dark)$/.test(t.theme)?t.theme:null,prefersDark:o.matches,runCount:0,jsCode:n,isDividerOrientAuto:!/^(horizontal|vertical)$/.test(t.dividerOrient),dividerOrient:/^(horizontal|vertical)$/.test(t.dividerOrient)?t.dividerOrient:getAutoDividerOrient(),isMovingDivider:!1,dividerPct:"50%",dividerSize:"8px",tempDividerPct:null,isMenuOpen:!1,isHistoryOpen:!1,commandHistory:[],historyIndex:null,historyDraft:null,valueMenu:null,toast:null,textScale:loadTextScale(),isFullscreen:!1,isMaximized:!1,isPopOut:i.isPopOut,isPoppedOut:!1,...i.popOutState??{}}),computed:{theme(){return this.forcedTheme??(this.prefersDark?"dark":"light")},modKey:()=>l?"\u2318":"Ctrl",runnerDescription(){return"window"===this.runnerMode?"This page (it can use the page's globals and DOM)":"A Web Worker (isolated from the page, no DOM)"},themeDescription(){return`${"dark"===this.theme?"Dark":"Light"} (${this.forcedTheme?"set by data-theme":"follows your system"})`},isTypeScript(){return"typescript"===this.language},builtWith(){var e=this.libraryVersions,e=["Vue "+e.vue,"Ace "+e["ace-builds"],"Prism "+e.prismjs,"Acorn "+e.acorn,...this.isTypeScript?["Babel "+e["@babel/standalone"]]:[]];return e.slice(0,-1).join(", ")+" and "+e[e.length-1]},blockTypeDescription(){return"module"===this.blockType?"Modules (top-level await and imports work, declarations stay in each block)":"Classic scripts (top-level declarations are shared between blocks)"},collapsedGroupIds(){return new Set(this.displays.filter(e=>e.groupId&&e.isCollapsed).map(e=>e.groupId))},layoutDescription(){return("vertical"===this.dividerOrient?"Editor beside the console":"Editor below the console")+(this.isDividerOrientAuto?" (automatic)":"")},exportCodeOptions:()=>[{value:"current",label:"Current code",note:"The code that already ran followed by the code in the editor."},{value:"original",label:"Original code",note:"The code this console started with."},{value:"blank",label:"Blank",note:"An empty console with the same settings."}],exportFormatOptions:()=>[{value:"snippet",label:"Embed snippet"},{value:"page",label:"Full page"}],exportNote(){return this.exportCodeOptions.find(e=>e.value===this.exportCode).note},originalGroups(){return extractHiddenGroups(this.originalCode,this.hidePrefix)},exportJsCode(){return"original"===this.exportCode?this.originalCode:"blank"===this.exportCode?"":this.currentCode},currentCode(){const e=this.runHistory.slice(),t=this.hiddenGroups.slice();let i=this.runCount;var s=()=>{for(;t.length&&t[0].runCount<=i;)e.push(t.shift().allLines)};s();for(const t of parseJSCodeGroups(this.jsCode))t.allLines.trim()&&(e.push(t.allLines),i++,s());return e.push(...t.map(e=>e.allLines)),joinCodeBlocks(e)},exportDataset(){const{librariesUrl:e,...i}=t;return i},exportHtml(){return buildConsoleHtml({code:this.exportJsCode,dataset:this.exportDataset,packageInfo:this.packageInfo,isFullPage:"page"===this.exportFormat})},bottomButtons(){var e=this.isFullscreen||this.isMaximized;return[{iconName:"more",title:"More",className:"more-button",callback(){this.toggleMenu()}},{iconName:"clear",title:"Clear console",callback(){this.clearConsole()}},{iconName:"history",title:`History (${l?"\u2325":"Alt+"}H)`,className:"history-button",callback(){this.toggleHistory()}},{iconName:"horizontalView",title:"Show the editor below the console",callback(){this.setDividerOrient("horizontal")},showIf(){return"horizontal"!==this.dividerOrient}},{iconName:"verticalView",title:"Show the editor beside the console",callback(){this.setDividerOrient("vertical")},showIf(){return"vertical"!==this.dividerOrient}},{iconName:e?"exitFullscreen":"fullscreen",title:e?"Exit full screen":"Full screen",callback(){this.toggleFullscreen()}},{iconName:this.runningCount?"spinner":"play",label:"Run",className:"primary",title:`Run the next block of code (${l?"\u2318":"Ctrl+"}Enter)`,callback(){this.runCode()},disableIf(){return!this.canRunCode}}].filter(e=>!e.showIf||e.showIf.call(this))},historyEntries(){return this.commandHistory.map((e,t)=>{var[i]=parseJSCodeGroups(e),e=(i?.lines??e).split("\n").filter(e=>e.trim());return{index:t,label:i?.headerLines||e[0]||"",detail:e.length+" line"+(1===e.length?"":"s")}}).reverse()},canShrinkText(){return this.textScale>TEXT_SCALES[0]},canGrowText(){return this.textScale<TEXT_SCALES[TEXT_SCALES.length-1]},canRunCode(){return this.jsCode.trim()},mainElemClassNames(){return["vertical"===this.dividerOrient?"col-orient":"row-orient",this.isMovingDivider?"is-moving-divider":""].join(" ")},mainElemStyles(){return{"--divider-size":this.dividerSize,"--editor-pct":this.dividerPct,"--temp-editor-pct":this.tempDividerPct}}},methods:{onEditorKeyCombo(e){(e.ctrlKey||e.metaKey)&&"Enter"===e.key&&this.canRunCode&&this.runCode()},runCode(){this.isDisplaysScrolledToBottom=!0;var[e,...t]=parseJSCodeGroups(this.jsCode),e=(this.runGroup(e),t.map(e=>e.allLines).join("\n"));null!==this.historyIndex?(this.jsCode=[e,this.historyDraft].filter(e=>e.trim()).join("\n"),this.historyIndex=this.historyDraft=null):(this.jsCode=e,this.runCount++)},navigateHistory(e){var t=this.commandHistory;if(e<0)return!!t.length&&(null===this.historyIndex&&(this.historyDraft=this.jsCode,this.historyIndex=t.length),0<this.historyIndex&&this.showHistoryCode(this.historyIndex-1,"start"),!0);if(null===this.historyIndex)return!1;if(this.historyIndex<t.length-1)this.showHistoryCode(this.historyIndex+1,"end");else{const e=this.historyDraft;this.historyIndex=this.historyDraft=null,this.setEditorCode(e,"end")}return!0},showHistoryCode(e,t){null===this.historyIndex&&(this.historyDraft=this.jsCode),this.historyIndex=e,this.setEditorCode(this.commandHistory[e],t)},setEditorCode(e,t){this.jsCode=e,this.$nextTick(()=>{var e=this.$refs.editor?.editor;e&&("end"===t?e.navigateFileEnd():e.navigateFileStart())})},onEditorHistoryKey(e){e.handled=this.navigateHistory(e.direction)},toggleHistory(){this.isHistoryOpen?this.isHistoryOpen=!1:(this.closeMenu(),this.closeValueMenu(),this.isHistoryOpen=!0,this.$nextTick(()=>this.$refs.historyPanel?.querySelector(".menu-item")?.focus()))},recallHistory(e){this.isHistoryOpen=!1,this.showHistoryCode(e,"start"),this.$nextTick(()=>this.$refs.editor?.editor.focus())},stopNavigatingHistory(){this.historyIndex=this.historyDraft=null},runHiddenGroups(){var{hiddenGroups:e}=this;e.length&&e[0].runCount<=this.runCount&&this.runGroup(e.shift())},runGroup(e){var{header:t,isHidden:i}=parseGroupHeader(e.headerLines,this.hidePrefix),t=(this.displays.push({type:"prism",header:t,isHidden:i,isCodeShown:!i,value:e.lines}),this.runningCount++,this.runHistory.push(e.allLines),e.allLines.trim()),{language:t,blockType:r}=(!i&&t&&this.commandHistory[this.commandHistory.length-1]!==t&&(this.commandHistory.push(t),200<this.commandHistory.length)&&this.commandHistory.shift(),this),e="typescript"===t?compileTypeScript(e.lines,{blockType:r}):{code:e.lines},{code:i,resultRange:l}=e.error?{code:"",resultRange:null}:prepareCode(e.code,{blockType:r,importsUrl:this.importsUrl,findResult:this.showResults&&!i});messageParent({target:"runner",func:"runCode",args:[i,{blockType:r,resultRange:l,language:t,sourceMap:e.sourceMap,compileError:e.error}]})},clearConsole(){this.displays=[],messageParent({target:"runner",func:"clearLogs",args:[]})},async resetConsole(){await this.confirm({title:"Reset the console?",message:"The output will be cleared and the editor will go back to the original code."+("window"===this.runnerMode?" Anything the code already defined on the page will stay defined.":""),confirmText:"Reset"})&&this.restart()},restart(){var{visibleCode:e,hiddenGroups:t}=this.originalGroups;this.displays=[],this.jsCode=e,this.hiddenGroups=t.map(e=>({...e})),this.runCount=0,this.runningCount=0,this.runHistory=[],this.stopNavigatingHistory(),messageParent({target:"runner",func:"reset",args:[]}),this.runHiddenGroups()},openFile(){this.closeMenu();var{fileInput:e}=this.$refs;e.value="",e.click()},async onFileChosen(e){var e=e.target.files?.[0],i;e&&(i=unindentMin(await e.text()),(this.displays.length||this.jsCode.trim())&&!await this.confirm({title:`Open ${e.name}?`,message:"The output will be cleared and the code in the editor will be replaced with the code in the file."+("window"===this.runnerMode?" Anything the code already defined on the page will stay defined.":""),confirmText:"Open"})||(this.fileName=e.name,this.originalCode=i,this.restart()))},async saveFile(){this.closeMenu();var e=this.currentCode+"\n",t=this.fileName||(this.isTypeScript?"js-box.ts":"js-box.js"),i=this.isTypeScript?{description:"TypeScript",accept:{"text/typescript":[".ts",".mts"]}}:{description:"JavaScript",accept:{"text/javascript":[".js",".mjs"]}};if("function"==typeof window.showSaveFilePicker)try{const s=await showSaveFilePicker({suggestedName:t,types:[i]}),o=await s.createWritable();return await o.write(e),await o.close(),void(this.fileName=s.name)}catch(e){if("AbortError"===e?.name)return}const s=URL.createObjectURL(new Blob([e],{type:Object.keys(i.accept)[0]}));Object.assign(document.createElement("a"),{href:s,download:t}).click(),setTimeout(()=>URL.revokeObjectURL(s),1e3)},async copyToEditor(e){this.jsCode.trim()&&this.jsCode!==e&&!await this.confirm({title:"Replace the code in the editor?",message:"The code that is currently in the editor will be replaced with a copy of the code you selected.",confirmText:"Replace"})||(this.stopNavigatingHistory(),this.jsCode=e)},confirm(e){return this.dialog?.resolve(!1),new Promise(t=>{this.dialog={...e,resolve:t},this.$nextTick(()=>this.$refs.dialogConfirmButton?.focus())})},openAbout(e){this.aboutTab=e,this.isAboutOpen=!0,this.$nextTick(()=>this.$refs.aboutCloseButton?.focus())},closeAbout(){this.isAboutOpen=!1},async copyExport(){var e=this.exportHtml;try{await navigator.clipboard.writeText(e)}catch(t){var e=Object.assign(document.createElement("textarea"),{value:e});document.body.appendChild(e),e.select(),document.execCommand("copy"),e.remove()}this.copyLabel="Copied!",clearTimeout(this.copyLabelTimeout),this.copyLabelTimeout=setTimeout(()=>this.copyLabel="Copy",1600)},downloadExport(){const e=buildConsoleHtml({code:this.exportJsCode,dataset:this.exportDataset,packageInfo:this.packageInfo,isFullPage:!0}),t=URL.createObjectURL(new Blob([e],{type:"text/html"}));Object.assign(document.createElement("a"),{href:t,download:"js-box.html"}).click(),setTimeout(()=>URL.revokeObjectURL(t),1e3)},onLogRowClick(e,t){e.groupId&&!t.target.closest(".js-value-header.expandable")&&(e.isCollapsed=!e.isCollapsed)},isInCollapsedGroup(e){const{collapsedGroupIds:t}=this;return!!t.size&&!!e.groupIds?.some(e=>t.has(e))},getState(){return JSON.parse(JSON.stringify({displays:this.displays,jsCode:this.jsCode,originalCode:this.originalCode,fileName:this.fileName,commandHistory:this.commandHistory,historyIndex:this.historyIndex,historyDraft:this.historyDraft,runHistory:this.runHistory,hiddenGroups:this.hiddenGroups,runCount:this.runCount,runningCount:this.runningCount,dividerOrient:this.dividerOrient,isDividerOrientAuto:this.isDividerOrientAuto,dividerPct:this.dividerPct}))},restoreState(e){Object.assign(this,e),this.isDisplaysScrolledToBottom=!0},toggleMenu(){this.isMenuOpen?this.closeMenu():(this.isHistoryOpen=!1,this.closeValueMenu(),this.isMenuOpen=!0,this.$nextTick(()=>this.$refs.moreMenu?.querySelector(".menu-item:not(:disabled)")?.focus()))},closeMenu(e){this.isMenuOpen=!1,e&&document.querySelector("#bottomNav .more-button")?.focus()},onMenuKeyDown(e){var t,i,s;"Escape"===e.key?(e.stopPropagation(),this.closeMenu(this.isMenuOpen),this.closeValueMenu(),this.isHistoryOpen=!1):"ArrowDown"!==e.key&&"ArrowUp"!==e.key||(e.preventDefault(),i=(t=[...e.currentTarget.querySelectorAll(".menu-item:not(:disabled)")]).indexOf(document.activeElement),t[(i+("ArrowDown"===e.key?1:t.length-1))%t.length]?.focus())},changeTextScale(e){var e=TEXT_SCALES.indexOf(this.textScale)+e;0<=e&&e<TEXT_SCALES.length&&this.setTextScale(TEXT_SCALES[e])},setTextScale(e){this.textScale=e;try{localStorage.setItem("yourjs-box.textScale",""+e)}catch(e){}},async toggleFullscreen(){if(this.isMaximized)this.setMaximized(!1);else if(document.fullscreenElement)await document.exitFullscreen();else try{await document.documentElement.requestFullscreen()}catch(e){this.isPopOut||this.setMaximized(!0)}},setMaximized(e){this.isMaximized=e,messageParent({target:"host",func:"setMaximized",args:[e]})},popOut(){this.closeMenu(),this.isMaximized&&this.setMaximized(!1),messageParent({target:"host",func:"popOut",args:[this.getState()]})},bringBack(){this.hasSentState=!0;var e=window.yourjsBoxPopIn;"function"==typeof e?e(this.getState()):messageParent({target:"host",func:"popIn",args:[this.getState()]})},focusPopOut(){messageParent({target:"host",func:"focusPopOut",args:[]})},requestPopIn(){messageParent({target:"host",func:"requestPopIn",args:[]})},onWindowMouseDown(e){this.isMenuOpen&&!e.target.closest(".more-menu, .more-button")&&this.closeMenu(),this.valueMenu&&!e.target.closest(".value-menu")&&this.closeValueMenu(),this.isHistoryOpen&&!e.target.closest(".history-panel, .history-button")&&(this.isHistoryOpen=!1)},onWindowKeyDown(e){!e.altKey||e.ctrlKey||e.metaKey||"KeyH"!==e.code?"Escape"===e.key&&this.valueMenu?this.closeValueMenu():"Escape"!==e.key||!this.isMaximized||this.isMenuOpen||this.dialog||this.isAboutOpen||this.setMaximized(!1):(e.preventDefault(),e.stopPropagation(),this.toggleHistory())},openValueMenu(e,{path:t,keyPath:i,isPrimitive:s}){this.closeMenu(),this.valueMenu={x:e.clientX,y:e.clientY,path:t.slice(),propertyPath:i?.length?formatPropertyPath(i):null,fileName:i?.length&&/^[\w$-]+$/.test(i[i.length-1])?i[i.length-1]:"value",isPrimitive:s},this.$nextTick(()=>{var e=this.$refs.valueMenu,t,i;e&&this.valueMenu&&({width:t,height:i}=e.getBoundingClientRect(),this.valueMenu.x=Math.max(4,Math.min(this.valueMenu.x,innerWidth-t-4)),this.valueMenu.y=Math.max(4,Math.min(this.valueMenu.y,innerHeight-i-4)),e.querySelector(".menu-item")?.focus())})},closeValueMenu(){this.valueMenu=null},requestValueJson(e){const t=Date.now()+"-"+Math.random();return new Promise(i=>{jsonRequests.set(t,i),messageParent({target:"runner",func:"getValueAsJson",args:[e,t]})})},showToast(e){clearTimeout(this.toastTimeout),this.toast={message:e},this.toastTimeout=setTimeout(()=>this.toast=null,3500)},showJsonToast({circularCount:e,error:t},i){this.showToast(t||i+(e?` (${e} circular reference${1===e?" was":"s were"} left out)`:""))},async copyValueAsJson(){const e=[...this.valueMenu.path];this.closeValueMenu();var t=this.requestValueJson(e);try{if(window.ClipboardItem&&navigator.clipboard?.write)await navigator.clipboard.write([new ClipboardItem({"text/plain":t.then(({json:e,error:t})=>{if(t)throw new Error(t);return new Blob([e],{type:"text/plain"})})})]);else{const{json:e,error:i}=await t;if(i)throw new Error(i);await navigator.clipboard.writeText(e)}this.showJsonToast(await t,"Copied as JSON")}catch(e){var t=await t;this.showToast(t.error||"The value couldn't be copied. Your browser may not allow copying here.")}},async saveValueAsJson(){const{fileName:e}=this.valueMenu,t=[...this.valueMenu.path];this.closeValueMenu();var i=this.requestValueJson(t),s=e+".json";let o;if("function"==typeof window.showSaveFilePicker)try{o=await showSaveFilePicker({suggestedName:s,types:[{description:"JSON",accept:{"application/json":[".json"]}}]})}catch(e){if("AbortError"===e?.name)return}var i=await i;if(i.error)this.showToast(i.error);else{var n=i.json+"\n";if(o){const e=await o.createWritable();await e.write(n),await e.close()}else{const e=URL.createObjectURL(new Blob([n],{type:"application/json"}));Object.assign(document.createElement("a"),{href:e,download:s}).click(),setTimeout(()=>URL.revokeObjectURL(e),1e3)}this.showJsonToast(i,"Saved as JSON")}},storeValueAsGlobal(){var e=[...this.valueMenu.path];this.closeValueMenu(),messageParent({target:"runner",func:"storeAsGlobal",args:[e]})},async copyPropertyPath(){var{propertyPath:e}=this.valueMenu;this.closeValueMenu();try{await navigator.clipboard.writeText(e),this.showToast("Copied "+e)}catch(e){this.showToast("The property path couldn't be copied. Your browser may not allow copying here.")}},refreshValue(){var e=[...this.valueMenu.path];this.closeValueMenu(),messageParent({target:"runner",func:"refreshDescription",args:[e]})},closeDialog(e){var{dialog:t}=this;this.dialog=null,t?.resolve(e)},setDividerOrient(e){this.isDividerOrientAuto=!1,this.dividerOrient=e},onWindowResize(){this.isDividerOrientAuto&&(this.dividerOrient=getAutoDividerOrient())},onDisplaysScroll(){this.closeValueMenu();var{scrollTop:e,scrollHeight:t,clientHeight:i}=this.$refs.displaysScroller;this.isDisplaysScrolledToBottom=t-e-i<8},getEditorPct(e){var t=this.$refs.main.getBoundingClientRect(),{dividerOrient:i}=this,s=e.pageX-t.left,e=e.pageY-t.top,r=t.width,t=t.height;return 100-100*Math.min(Math.max(.2,"vertical"===i?s/r:e/t),.8)+"%"},onMainElemMouseDown(e){e.target===this.$refs.mainDivider&&(this.isMovingDivider=!0,this.tempDividerPct=this.getEditorPct(e))},onWindowMouseMove(e){this.isMovingDivider&&(this.tempDividerPct=this.getEditorPct(e))},onWindowMouseUp(e){this.isMovingDivider&&(this.isMovingDivider=!1,this.dividerPct=this.getEditorPct(e))},onWindowError(e){this.displays.push({type:"error",message:e.error?.stack??e.message??e.error?.message??""+e.error,line:e.lineno,column:e.colno})}},watch:{textScale:{handler(e){document.documentElement.style.setProperty("--text-scale",e)},immediate:!0},theme:{handler(e){document.documentElement.dataset.theme=e},immediate:!0},"displays.length"(){this.isDisplaysScrolledToBottom&&this.$nextTick(()=>{var e=this.$refs.displaysScroller;e.scrollTop=e.scrollHeight})}},mounted(){addEventListener("mousemove",this.onWindowMouseMove),addEventListener("mousedown",this.onWindowMouseDown),addEventListener("keydown",this.onWindowKeyDown,!0),addEventListener("resize",this.onWindowResize),addEventListener("mouseup",this.onWindowMouseUp),addEventListener("error",this.onWindowError),o.addEventListener("change",e=>this.prefersDark=e.matches),document.addEventListener("fullscreenchange",()=>this.isFullscreen=!!document.fullscreenElement),this.isPopOut&&addEventListener("pagehide",()=>this.hasSentState||this.bringBack()),this.runningCount||this.runHiddenGroups(),setTimeout(()=>document.querySelector("#splash").classList.add("hidden"),Math.max(0,(this.isPopOut?0:1e3)-performance.now()))}}).component("ace-editor",getAceComponentProps()).component("prism",getPrismComponentProps()).component("icon",getIconComponentProps()).component("js-value",getJSValueComponentProps()).mount(document.querySelector("#vueApp"))}}function getAceComponentProps(){return{data:()=>({annotations:[]}),props:["fontSize","height","keybinding","language","modelValue","readOnly","theme","width"],computed:{infoNotes(){return this.annotations.filter(({type:e})=>"info"===e)},warningNotes(){return this.annotations.filter(({type:e})=>"warning"===e)},errorNotes(){return this.annotations.filter(({type:e})=>"error"===e)},style(){return{height:null!=this.height?"number"==typeof this.height?this.height+"px":this.height:"150px",width:null!=this.width?"number"==typeof this.width?this.width+"px":this.width:"100%"}},modeSig(){return"ace/mode/"+(this.language??"text")},themeSig(){return"ace/theme/"+(""+(this.theme??"light")).replace(/^light$|(^dark$)/i,(e,t)=>"cloud_editor"+(t?"_dark":""))}},watch:{themeSig(e){this.editor.setTheme(e)},fontSize(e){e&&this.editor.setFontSize(e)},modelValue(e){e!==this.editor.getValue()&&this.editor.setValue(e,-1)}},async mounted(){const e=ace.edit(this.$refs.editor,{value:this.modelValue,mode:this.modeSig,theme:this.themeSig});this.editor=e,this.fontSize&&e.setFontSize(this.fontSize),this.readOnly&&(e.setReadOnly(!0),e.setHighlightActiveLine(!1),e.session.setUseWorker(!1)),e.setKeyboardHandler("ace/keyboard/vscode"),e.commands.removeCommand("addLineAfter"),e.commands.removeCommand("addLineBefore"),e.on("change",()=>this.$emit("update:modelValue",e.getValue())),e.session.on("changeAnnotation",()=>{var t=JSON.stringify(this.errorNotes),i=JSON.stringify(this.infoNotes),s=JSON.stringify(this.warningNotes),{errorNotes:o,infoNotes:r,warningNotes:n}=(this.annotations=e.getSession().getAnnotations(),this);t!==JSON.stringify(o)&&this.$emit("changeErrorNotes",o),i!==JSON.stringify(r)&&this.$emit("changeInfoNotes",r),s!==JSON.stringify(n)&&this.$emit("changeWarningNotes",n)}),this.$refs.editor.addEventListener("keydown",t=>{var i="ArrowUp"===t.key,s,o,r,s;!i&&"ArrowDown"!==t.key||t.shiftKey||t.altKey||t.ctrlKey||t.metaKey||!e.selection.isEmpty()||({row:s,column:o}=e.getCursorPosition(),r=e.session.getLength()-1,(i?0===s&&0===o:s===r&&o===e.session.getLine(r).length)&&(this.$emit("historyKey",s={direction:i?-1:1,handled:!1}),s.handled)&&(t.preventDefault(),t.stopPropagation()))},!0),e.textInput.getElement().addEventListener("keydown",e=>{16!==e.keyCode&&17!==e.keyCode&&18!==e.keyCode&&91!==e.keyCode&&92!==e.keyCode&&93!==e.keyCode&&(e.metaKey||e.ctrlKey||e.altKey||e.shiftKey&&1<(e.key??"").length)&&this.$emit("keyCombo",e)})},template:'<div ref="editor" :style="style"></div>'}}function getPrismComponentProps(){return{data:()=>({annotations:[]}),props:["code","isDark","language","lineNumbers","matchBraces"],computed:{html(){},preStyle(){return{filter:!1!==(this.isDark??!1)?"none":"invert(1) hue-rotate(180deg) brightness(1.1)",margin:0,paddingTop:"0.5em",paddingBottom:"0.5em"}}},watch:{code(){this.redraw()},language(){this.redraw()},lineNumbers(){this.redraw()},matchBraces(){this.redraw()}},methods:{async redraw(){const e=this.$refs.pre,t=this.$refs.code;t.textContent=this.code,t.className="language-"+(this.language??"javascript"),e.className="";for(const t of["lineNumbers","matchBraces"]){var i;null!=this[t]&&(i=t.replace(/[A-Z]+/g,"-$&").toLowerCase(),e.className+=" "+i)}Prism.highlightElement(t)}},async mounted(){await this.redraw()},template:'<pre ref="pre" :style="preStyle"><code ref="code"></code></pre>'}}function getIconComponentProps(){return{props:["name"],computed:{svgCode(){var e={missing:'<svg viewBox="0 0 32 32"><circle cx="16" cy="22.5" r="1.5" fill="currentColor"/><path fill="currentColor" d="M17 19h-2v-4h2c1.103 0 2-.897 2-2s-.897-2-2-2h-2c-1.103 0-2 .897-2 2v.5h-2V13c0-2.206 1.794-4 4-4h2c2.206 0 4 1.794 4 4s-1.794 4-4 4z"/><path fill="currentColor" d="M29.391 14.527L17.473 2.609A2.078 2.078 0 0 0 16 2c-.533 0-1.067.203-1.473.609L2.609 14.527C2.203 14.933 2 15.466 2 16s.203 1.067.609 1.473L14.526 29.39c.407.407.941.61 1.474.61s1.067-.203 1.473-.609L29.39 17.474c.407-.407.61-.94.61-1.474s-.203-1.067-.609-1.473M16 28.036L3.965 16L16 3.964L28.036 16z"/></svg>',trash:'<svg viewBox="0 0 15 15"><path fill="currentColor" fill-rule="evenodd" d="M5.5 1a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1zM3 3.5a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 0 1H11v8a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V4h-.5a.5.5 0 0 1-.5-.5M5 4h5v8H5z" clip-rule="evenodd"/></svg>',play:'<svg viewBox="0 0 16 16"><path fill="currentColor" d="M2 1v14l12-7z"/></svg>',refresh:'<svg viewBox="0 0 15 15"><path fill="currentColor" fill-rule="evenodd" d="M1.903 7.297c0 3.044 2.207 5.118 4.686 5.547a.521.521 0 1 1-.178 1.027C3.5 13.367.861 10.913.861 7.297c0-1.537.699-2.745 1.515-3.663c.585-.658 1.254-1.193 1.792-1.602H2.532a.5.5 0 0 1 0-1h3a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-1 0V2.686l-.001.002c-.572.43-1.27.957-1.875 1.638c-.715.804-1.253 1.776-1.253 2.97m11.108.406c0-3.012-2.16-5.073-4.607-5.533a.521.521 0 1 1 .192-1.024c2.874.54 5.457 2.98 5.457 6.557c0 1.537-.699 2.744-1.515 3.663c-.585.658-1.254 1.193-1.792 1.602h1.636a.5.5 0 1 1 0 1h-3a.5.5 0 0 1-.5-.5v-3a.5.5 0 1 1 1 0v1.845h.002c.571-.432 1.27-.958 1.874-1.64c.715-.803 1.253-1.775 1.253-2.97" clip-rule="evenodd"/></svg>',horizontalView:'<svg viewBox="0 0 15 15"><path fill="currentColor" fill-rule="evenodd" d="M1.5 2h12a.5.5 0 0 1 .5.5V7H1V2.5a.5.5 0 0 1 .5-.5M1 8v4.5a.5.5 0 0 0 .5.5h12a.5.5 0 0 0 .5-.5V8zM0 2.5A1.5 1.5 0 0 1 1.5 1h12A1.5 1.5 0 0 1 15 2.5v10a1.5 1.5 0 0 1-1.5 1.5h-12A1.5 1.5 0 0 1 0 12.5z" clip-rule="evenodd"/></svg>',verticalView:'<svg viewBox="0 0 15 15"><path fill="currentColor" fill-rule="evenodd" d="M8 2h5.5a.5.5 0 0 1 .5.5v10a.5.5 0 0 1-.5.5H8zM7 2H1.5a.5.5 0 0 0-.5.5v10a.5.5 0 0 0 .5.5H7zm-7 .5A1.5 1.5 0 0 1 1.5 1h12A1.5 1.5 0 0 1 15 2.5v10a1.5 1.5 0 0 1-1.5 1.5h-12A1.5 1.5 0 0 1 0 12.5z" clip-rule="evenodd"/></svg>',error:'<svg viewBox="0 0 24 24"><path fill="currentColor" d="M11 15h2v2h-2zm0-8h2v6h-2zm1-5C6.47 2 2 6.5 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 18a8 8 0 0 1-8-8a8 8 0 0 1 8-8a8 8 0 0 1 8 8a8 8 0 0 1-8 8"/></svg>',history:'<svg viewBox="0 0 16 16"><path d="M2.5 8a5.5 5.5 0 1 0 1.6-3.9" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><path d="M2.25 2.5v2.75H5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M8 5v3.25l2.25 1.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',copy:'<svg viewBox="0 0 16 16"><rect x="5.5" y="5.5" width="8" height="8" rx="1.25" fill="none" stroke="currentColor" stroke-width="1.4"/><path d="M10.5 3.5v-.75A1.25 1.25 0 0 0 9.25 1.5h-5A1.25 1.25 0 0 0 3 2.75v5A1.25 1.25 0 0 0 4.25 9h.75" fill="none" stroke="currentColor" stroke-width="1.4"/></svg>',variable:'<svg viewBox="0 0 16 16"><path d="M5 2.5c-1.5 1.5-2 3.5-2 5.5s.5 4 2 5.5M11 2.5c1.5 1.5 2 3.5 2 5.5s-.5 4-2 5.5M6.5 6l3 4M9.5 6l-3 4" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>',path:'<svg viewBox="0 0 16 16"><circle cx="3.5" cy="12.5" r="1.5" fill="currentColor"/><circle cx="12.5" cy="3.5" r="1.5" fill="currentColor"/><path d="M3.5 11V8a2 2 0 0 1 2-2h5a2 2 0 0 0 2-2" fill="none" stroke="currentColor" stroke-width="1.4"/></svg>',open:'<svg viewBox="0 0 16 16"><path d="M2 4.5a1 1 0 0 1 1-1h3.2l1.3 1.5H13a1 1 0 0 1 1 1V12a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/></svg>',save:'<svg viewBox="0 0 16 16"><path d="M8 2.5v7M5 7l3 3 3-3M3 11.5v1.5h10v-1.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',fullscreen:'<svg viewBox="0 0 16 16"><path d="M2.5 6V2.5H6M10 2.5h3.5V6M13.5 10v3.5H10M6 13.5H2.5V10" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',exitFullscreen:'<svg viewBox="0 0 16 16"><path d="M6 2.5V6H2.5M13.5 6H10V2.5M10 13.5V10h3.5M2.5 10H6v3.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',more:'<svg viewBox="0 0 16 16"><circle cx="3.5" cy="8" r="1.4" fill="currentColor"/><circle cx="8" cy="8" r="1.4" fill="currentColor"/><circle cx="12.5" cy="8" r="1.4" fill="currentColor"/></svg>',popOut:'<svg viewBox="0 0 16 16"><path d="M9.5 2.5h4v4M13.5 2.5L8 8M12 9.5v3a1 1 0 0 1-1 1H3.5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h3" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',popIn:'<svg viewBox="0 0 16 16"><path d="M12 8.5H8V4.5M8 8.5l5.5-5.5M12 10.5v2a1 1 0 0 1-1 1H3.5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h2" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',code:'<svg viewBox="0 0 16 16"><path d="M5.5 4.5L2 8l3.5 3.5M10.5 4.5L14 8l-3.5 3.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',info:'<svg viewBox="0 0 16 16"><circle cx="8" cy="8" r="6.25" fill="none" stroke="currentColor" stroke-width="1.5"/><path d="M8 7.25v4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="8" cy="5" r="1" fill="currentColor"/></svg>',result:'<svg viewBox="0 0 16 16"><path d="M9 4.5L5.5 8 9 11.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><circle cx="12" cy="8" r="1.1" fill="currentColor"/></svg>',close:'<svg viewBox="0 0 16 16"><path d="M4 4l8 8m0-8l-8 8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>',clear:'<svg viewBox="0 0 16 16"><circle cx="8" cy="8" r="6" fill="none" stroke="currentColor" stroke-width="1.5"/><path d="M3.75 12.25l8.5-8.5" stroke="currentColor" stroke-width="1.5"/></svg>',copyToEditor:'<svg viewBox="0 0 16 16"><path d="M6 3.5L2.5 7 6 10.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 7h6.5a4 4 0 0 1 4 4v1.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>',spinner:'<svg viewBox="0 0 16 16" class="spin"><path d="M8 1.75a6.25 6.25 0 1 1-6.25 6.25" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round"/></svg>',chevron:'<svg viewBox="0 0 16 16"><path d="M6 4l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',consoleError:'<svg viewBox="0 0 16 16"><circle cx="8" cy="8" r="7" fill="currentColor"/><path d="M5.5 5.5l5 5m0-5l-5 5" stroke="#fff" stroke-width="1.75" stroke-linecap="round"/></svg>',consoleWarning:'<svg viewBox="0 0 16 16"><path d="M8 1.75L14.75 14H1.25z" fill="currentColor" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M8 6v3.5" stroke="#202124" stroke-width="1.75" stroke-linecap="round"/><circle cx="8" cy="11.75" r="1" fill="#202124"/></svg>'};return(e[this.name]??e.missing).replace("<svg",'$& xmlns="http://www.w3.org/2000/svg" style="height: 1em; width: 1em; display: inline-block; transform: translateY(0.1em);"')}},template:'<span v-html="svgCode"></span>'}}function getJSValueComponentProps(){return{props:["description","path","name","isDimName","keyPath"],data:()=>({isExpanded:!1,hasBeenExpanded:!1}),watch:{isExpanded(e){e&&!this.hasBeenExpanded&&(this.hasBeenExpanded=e)},isPartialDescription(e){e&&this.isExpanded&&this.requestDescription()}},computed:{isPartialDescription(){return void 0===this.description.entries},isExpandable(){return!this.description.isPrimitive},isEntry(){return null!=this.name},classNames(){return["js-value",this.isEntry||this.isExpandable&&this.isExpanded?"d-block":"d-inline-block",this.isExpanded?"expanded":""]},entryGroups(){const{keyPath:e,description:t}=this;return[{key:"entries",isDim:e=>!1===e[2],getKeyPath:i=>e&&t.entriesArePropertyKeys?e.concat([i[0]]):null},{key:"protoEntries",isDim:()=>!0,getKeyPath:()=>e}]}},methods:{toggleExpanded(){this.isExpandable&&(this.isExpanded=!this.isExpanded,this.isExpanded)&&this.isPartialDescription&&this.requestDescription()},requestDescription(){messageParent({target:"runner",func:"sendDescriptionFor",args:[this.path]})},openMenu(e){this.$root.openValueMenu(e,{path:this.path,keyPath:this.keyPath,isPrimitive:this.description.isPrimitive})}},template:'\n <div :class="classNames">\n <div :class="[\'js-value-header\', isExpandable ? \'expandable\' : \'\']" @click="toggleExpanded" @contextmenu.prevent.stop="openMenu"><span\n v-if="isExpandable || isEntry" :class="[\'arrow\', isExpandable ? \'expandable\' : \'\', isExpanded ? \'expanded\' : \'\']"></span><template\n v-if="isEntry"><span :class="[\'entry-key\', isDimName ? \'dim\' : \'\']">{{ name }}</span>: </template><span\n v-for="part in description.parts" :class="\'t-\' + part[0]">{{ part[1] }}</span></div>\n <div v-if="hasBeenExpanded" v-show="isExpanded" class="expansion">\n <div v-if="isPartialDescription" class="loading">Loading&hellip;</div>\n <template v-else>\n <template v-for="group in entryGroups">\n <js-value\n v-for="(entry, entryIndex) in description[group.key]"\n :name="entry[0]"\n :is-dim-name="group.isDim(entry)"\n :description="entry[1]"\n :key-path="group.getKeyPath(entry)"\n :path="path.concat([group.key, entryIndex])">\n </js-value>\n </template>\n </template>\n </div>\n </div>\n '}}function parseJSCodeGroups(e){return e.split(/\r\n|\r|\n/).reduce((e,t)=>{var i=e[e.length-1],s=/^\/\/[^]*\\\\$/.test(t),o=s?t.replace(/^\/+\s*|\s*\\+$/g,""):t;return!e.length||s&&!i.canAppendHeader?e.push({headerLines:s?[o]:[],lines:s?[]:[t],allLines:[t],canAppendHeader:s}):(s?i.headerLines.push(o):(i.canAppendHeader=!1,i.lines.push(t)),i.allLines.push(t)),e},[]).reduce((e,t)=>(t.canAppendHeader||(delete t.canAppendHeader,t.headerLines=t.headerLines.join("\n").trimEnd(),t.lines=t.lines.join("\n"),t.allLines=t.allLines.join("\n"),e.push(t)),e),[])}function parseGroupHeader(e,t){var i=!!t&&e.startsWith(t);return{header:i?e.slice(t.length).replace(/^\s*:?\s*/,""):e,isHidden:i}}function extractHiddenGroups(e,t){var i=[],s=[];for(const o of parseJSCodeGroups(e))parseGroupHeader(o.headerLines,t).isHidden?s.push({...o,runCount:i.length}):i.push(o);return{visibleCode:i.map(e=>e.allLines).join("\n"),hiddenGroups:s}}function compileTypeScript(e,{blockType:t}){try{var i=Babel.transform(e,{filename:"snippet.ts",presets:[["typescript",{allExtensions:!0,onlyRemoveTypeImports:!0}]],sourceType:"module"===t?"module":"script",parserOpts:{allowImportExportEverywhere:"module"!==t},retainLines:!0,sourceMaps:!0});return{code:i.code,sourceMap:decodeSourceMap(i.map.mappings)}}catch(t){if("SyntaxError"===t?.name&&t.loc)return{code:e,error:{message:(""+t.message).split("\n")[0].replace(/^\/?snippet\.ts:\s*/,"").replace(/\s*\(\d+:\d+\)$/,""),line:t.loc.line,column:t.loc.column+1}};throw t}}function decodeSourceMap(e){const t=[0,0,0,0,0];return e.split(";").map(e=>{t[0]=0;const i=[];for(const s of e.split(","))if(s){const e=[];let o=0,r=0;for(const t of s){const i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(t);o+=(31&i)<<r,32&i?r+=5:(e.push(1&o?-(o>>>1):o>>>1),o=r=0)}e.forEach((e,i)=>t[i]+=e),4<=e.length&&i.push([t[0],t[2],t[3]])}return i.sort((e,t)=>e[0]-t[0])})}function prepareCode(e,{blockType:t,importsUrl:i,findResult:s}){if(!window.acorn)return{code:e,resultRange:null};let o;try{o=acorn.parse(e,{ecmaVersion:"latest",sourceType:"module"===t?"module":"script",allowHashBang:!0})}catch(t){return{code:e,resultRange:null}}let r=null;if(s){const e=o.body[o.body.length-1];"ExpressionStatement"!==e?.type||e.directive||(r=[e.expression.start,e.expression.end])}const n=[];i&&walkAst(o,e=>{var{source:e}=/^(Import(Declaration|Expression)|Export(All|Named)Declaration)$/.test(e.type)?e:{};"Literal"===e?.type&&"string"==typeof e.value&&isBareSpecifier(e.value)&&n.push({start:e.start,end:e.end,text:JSON.stringify(i.replace(/\{specifier\}/g,e.value))})}),n.sort((e,t)=>t.start-e.start);for(const{start:t,end:i,text:s}of n){e=e.slice(0,t)+s+e.slice(i);const o=s.length-(i-t);r=r&&r.map(e=>e>=i?e+o:e)}return{code:e,resultRange:r}}function formatPropertyPath(e){return e.map((e,t)=>/^(0|[1-9]\d*)$/.test(e)?`[${e}]`:/^[A-Za-z_$][\w$]*$/.test(e)?(t?".":"")+e:`[${JSON.stringify(e)}]`).join("")}function isBareSpecifier(e){return!/^(\.{0,2}\/|#|[a-z][a-z\d+.-]*:)/i.test(e)}function walkAst(e,t){if(Array.isArray(e))for(const i of e)walkAst(i,t);else if(e&&"string"==typeof e.type){t(e);for(const i of Object.keys(e)){var s=e[i];s&&"object"==typeof s&&walkAst(s,t)}}}function joinCodeBlocks(e){return e.map(e=>e.replace(/^(\s*[\r\n])+|\s+$/g,"")).filter(Boolean).map((e,t)=>{var i=e.split(/\r\n|\r|\n/)[0];return t&&!/^\/\/[^]*\\\\$/.test(i)?`// \\\\
6
6
  `+e:e}).join("\n\n")}function buildConsoleHtml({code:e,dataset:t,packageInfo:i,isFullPage:s}){const{name:o,version:r}=i,n=`https://cdn.jsdelivr.net/npm/${o}@${r.split(".")[0]}/dist/${o}.min.js`,a=Object.entries(t).map(([e,t])=>` data-${e.replace(/[A-Z]/g,e=>"-"+e.toLowerCase())}="${escapeHtmlAttribute(t)}"`).join(""),l=s?" ":" ",c=e.replace(/<\/(script)/gi,"<\\/$1").replace(/<!--/g,"<\\!--"),d=(c.trim()?[`<script src="${n}"${a}>`,...c.split("\n").map(e=>e.trim()?" "+e:""),"<\/script>"]:[`<script src="${n}"${a}></script>`]).map(e=>e&&l+e).join("\n");return s?["<!DOCTYPE html>",'<html lang="en">'," <head>",' <meta charset="utf-8">',' <meta name="viewport" content="width=device-width, initial-scale=1">'," <title>JS Box</title>"," <style>"," html, body { height: 100%; margin: 0; }"," </style>"," </head>"," <body>",d," </body>","</html>",""].join("\n"):`<div style="height: 400px;">
7
7
  ${d}
8
8
  </div>
9
- `}function escapeHtmlAttribute(e){return(""+e).replace(/[&"<>]/g,e=>`&#${e.charCodeAt(0)};`)}function unindentMin(e,t){var i=(t=Object(t)).tabSize??4,t=t.trim??!0;if(e=e.replace(/\t/g," ".repeat(i)),!/(^|[\r\n])\S/.test(e)){const t=/(^|[\r\n])((?:(?!\r|\n)\s)+)(?=(\S)?)/g;let i=1/0;for(let s;s=t.exec(e);)s[3]&&(i=Math.min(i,s[2].length));e=e.replace(t,(e,t,s)=>t+s.slice(i))}return t?e.replace(/^(\s*[\r\n]+)+|\s+$/g,""):e}function sanitizeDescription(e){return{typeName:""+(e=Object(e)).typeName,isPrimitive:!!e.isPrimitive,parts:Array.from(e.parts??[],e=>[/^[a-z]+$/.test(Object(e)[0])?e[0]:"text",""+Object(e)[1]]),...sanitizeEntries(e),...null!=e.entriesArePropertyKeys?{entriesArePropertyKeys:!!e.entriesArePropertyKeys}:{}}}function sanitizeEntries(e){e=Object(e);var t={};for(const i of["entries","protoEntries"])Array.isArray(e[i])&&(t[i]=e[i].map(e=>[""+Object(e)[0],sanitizeDescription(Object(e)[1]),!1!==Object(e)[2]]));return t}function appendLog({logId:e,key:t,descriptions:i,table:s,groupIds:o,groupId:r,isCollapsed:n,stack:a}){t=""+t,mountedApp.displays.push({type:"log",key:t,name:"result"===t?"Result":"console."+t,descriptions:Array.from(i,sanitizeDescription),table:s?{headers:Array.from(s.headers,e=>""+e),rows:Array.from(s.rows,e=>({index:""+e.index,cells:Array.from(e.cells,e=>e&&sanitizeDescription(e))}))}:null,groupIds:Array.from(o??[],e=>""+e),groupId:null!=r?""+r:null,isCollapsed:!!n,stack:null!=a?""+a:null,logId:""+e})}function appendError({message:e,line:t,column:i}){mountedApp.displays.push({type:"error",message:""+e,line:+t,column:+i})}function updateDescriptionFor(e,t){const i=(e=Array.from(e)).shift(),s=mountedApp.displays.find(e=>"log"===e.type&&e.logId===i);let o=s?.descriptions[toIndex(e.shift())];for(let t=0;o&&t<e.length;t+=2){const i=e[t];if("entries"!==i&&"protoEntries"!==i)return;o=o[i]?.[toIndex(e[t+1])]?.[1]}if(o&&(Object.assign(o,sanitizeEntries(t)),o.entriesArePropertyKeys=!!Object(t).entriesArePropertyKeys,Array.isArray(Object(t).parts))){const{typeName:e,isPrimitive:i,parts:s}=sanitizeDescription(t);Object.assign(o,{typeName:e,isPrimitive:i,parts:s})}}function onValueJson(e){var{requestId:e,json:i,circularCount:s,error:o}=Object(e),r=jsonRequests.get(""+e);r&&(jsonRequests.delete(""+e),r({json:null!=i?""+i:null,circularCount:+s||0,error:null!=o?""+o:null}))}const jsonRequests=new Map;function onStoredAsGlobal(e){mountedApp.displays.push({type:"notice",message:"Stored as the global variable "+e})}function onCodeRan(){mountedApp.runningCount=Math.max(0,mountedApp.runningCount-1),mountedApp.runHiddenGroups()}function setPoppedOut(e,t){mountedApp.isPoppedOut=e,t&&mountedApp.restoreState(t)}function popIn(){mountedApp.bringBack()}function onPopOutFailed(){mountedApp.displays.push({type:"notice",message:"The pop-out window was blocked by the browser. Allow pop-ups for this site and try again."})}function clearDisplays(){mountedApp.displays=[{type:"notice",message:"Console was cleared"}]}function toIndex(e){return Number.isInteger(e)&&0<=e?e:void 0}},jsUrls:[libraryUrl("vue","dist/vue.global.prod.js"),libraryUrl("ace-builds","src-noconflict/ace.js"),libraryUrl("prismjs","components/prism-core.min.js"),libraryUrl("prismjs","plugins/autoloader/prism-autoloader.min.js"),libraryUrl("prismjs","plugins/match-braces/prism-match-braces.min.js"),libraryUrl("acorn","dist/acorn.js"),..."typescript"==language?[libraryUrl("@babel/standalone","babel.min.js")]:[]],cssUrls:["data:text/css,"+encodeURIComponent(VIEWER_IFRAME_CSS),libraryUrl("prism-themes","themes/prism-vsc-dark-plus.min.css"),libraryUrl("prismjs","plugins/match-braces/prism-match-braces.min.css")],head:targetWindow?'<meta charset="utf-8"><title>JS Box</title>':"",htmlAttributes:'data-theme="'+theme+'"',targetWindow:targetWindow,onMessage(message){relayMessage(message.data,{runner:runner,host:{apply:(func,args)=>hostFuncs[func](...args)}})},async onReady(){this.call("init",code,dataset,{runnerMode:runnerMode,blockType:blockType,language:language,showResults:showResults,importsUrl:importsUrl,packageInfo:PACKAGE_INFO,libraryVersions:LIBRARY_VERSIONS,isPopOut:!!targetWindow,popOutState:state??null})},body:VIEWER_IFRAME_HTML,style:{width:"100%",height:height||"100%",minHeight:"150px",border:0,display:"block"}})}addEventListener("pagehide",closePopOut),insert((inlineViewer=activeViewer=createViewer()).iframe);let isDestroyed=!1;return{element:inlineViewer.iframe,destroy(){isDestroyed||(isDestroyed=!0,popOutWindow&&(clearInterval(popOutWatcher),popOutViewer.dispose(),popOutWindow.close(),popOutWindow=null),removeEventListener("pagehide",closePopOut),runner.destroy(),inlineViewer.dispose(),inlineViewer.iframe.remove())}}}function createConsoleFromScript(script){createConsole({code:script.textContent,dataset:JSON.parse(JSON.stringify(script.dataset)),insert:element=>script.parentNode.insertBefore(element,script)})}const PLACEMENTS={fill:(target,element)=>target.replaceChildren(element),append:(target,element)=>target.append(element),prepend:(target,element)=>target.prepend(element),replace:(target,element)=>target.replaceWith(element),before:(target,element)=>target.before(element),after:(target,element)=>target.after(element)},CONSOLE_OPTION_NAMES=["blockType","dividerOrient","hidePrefix","importsUrl","language","librariesUrl","runner","showResults","theme"],YourJSBox=Object.freeze({version:PACKAGE_INFO.version,create(options){const{target,placement="fill",height,code=""}=options=Object(options),targetElement="string"==typeof target?document.querySelector(target):target;if(1!==targetElement?.nodeType)throw new TypeError("string"==typeof target?`YourJSBox.create(): no element matches the target ${JSON.stringify(target)}.`:"YourJSBox.create(): target must be an element or a CSS selector.");if(!Object.hasOwn(PLACEMENTS,placement))throw new TypeError(`YourJSBox.create(): placement must be one of ${Object.keys(PLACEMENTS).join(", ")}.`);var dataset={};for(const name of CONSOLE_OPTION_NAMES)null!=options[name]&&(dataset[name]=""+options[name]);return createConsole({code:""+code,dataset:dataset,height:"number"==typeof height?height+"px":null!=height?""+height:void 0,insert:element=>PLACEMENTS[placement](targetElement,element)})}});var createCallableFrame=function(){var IFRAME_SCRIPT_MESSAGE_CODE=parseFunction(function(){var HOST_WINDOW=window.opener||window.parent;function messageParent(message){HOST_WINDOW.postMessage(message,"*")}window.addEventListener("message",function(e){var data=e.data,func;e.source===HOST_WINDOW&&data&&/^[A-Za-z_$][\w$]*$/.test(data.funcName)&&Array.isArray(data.args)&&(func=eval(data.funcName),"function"==typeof func)&&func.apply(e,data.args)})}).body;function createCallableFrame(options){var jsCode=options.jsCode,onMessage=options.onMessage,onReady=options.onReady,style=options.style,isReady,READY_ID=Math.random()+""+Math.random(),jsCode=["(function(){",IFRAME_SCRIPT_MESSAGE_CODE,"var applyParent, callParent;","(function(READY_ID){",parseFunction(function(){applyParent=function(funcName,args){HOST_WINDOW.postMessage({funcName:funcName,args:args,id:READY_ID},"*")},callParent=function(funcName){HOST_WINDOW.postMessage({funcName:funcName,args:Array.prototype.slice.call(arguments,1),id:READY_ID},"*")};var interval=setInterval(function(){/^(complete|interactive)$/.test(document.readyState)&&(clearInterval(interval),messageParent(READY_ID))},100)}).body,"})("+JSON.stringify(READY_ID)+");","function"!=typeof jsCode?jsCode||"":parseFunction(jsCode).body,"})();"].join("\n").replace(/<(?=\/script|!--)/gi,"\\x3C"),TARGET_WINDOW=options.targetWindow,IFRAME=TARGET_WINDOW?null:document.createElement("iframe");function getFrameWindow(){return TARGET_WINDOW||IFRAME.contentWindow}var jsCode=["<!DOCTYPE html>","<html "+(options.htmlAttributes||"")+">","<head>",options.head||"",(options.cssUrls||[]).map(function(cssUrl){return'<link href="'+cssUrl+'" rel="stylesheet">'}).join("\n"),"</head>","<body>",options.body||"",(options.jsUrls||[]).map(function(jsUrl){return'<script src="'+jsUrl+'"><\/script>'}).join("\n"),"<script>"+jsCode+"<\/script>","</body>","</html>"].join("\n");if(TARGET_WINDOW?(TARGET_WINDOW.document.open(),TARGET_WINDOW.document.write(jsCode),TARGET_WINDOW.document.close()):(IFRAME.srcdoc=jsCode,IFRAME.setAttribute("allow","fullscreen")),style&&IFRAME)if("string"==typeof style)IFRAME.style.cssText=style;else for(var styleKey in style)hasOwn(style,styleKey)&&(IFRAME.style[styleKey]=style[styleKey]);function onWindowMessage(e){if(e.source===getFrameWindow()){var data=e.data,dataIsReadyId=READY_ID===data;if(isReady&&!dataIsReadyId)options.functions&&data.id===READY_ID&&hasOwn(options.functions,data.funcName)?options.functions[data.funcName].apply(callableFrame,data.args):"function"==typeof onMessage?onMessage.call(callableFrame,e):console.warn("Message sent from callable frame but no listener was set up.",e);else if(dataIsReadyId)for(isReady=!0,"function"==typeof onReady&&onReady.call(callableFrame,e);queuedMessages.length;)postToFrame(queuedMessages.shift());else console.warn("Message sent from callable frame prematurely:",e)}}addEventListener("message",onWindowMessage);var queuedMessages=[];function postToFrame(message){isReady?getFrameWindow().postMessage(message,"*"):queuedMessages.push(message)}var callableFrame={apply:function(funcName,args){postToFrame({funcName:funcName,args:args})},call:function(funcName){postToFrame({funcName:funcName,args:Array.prototype.slice.call(arguments,1)})},iframe:IFRAME,window:TARGET_WINDOW,dispose:function(){removeEventListener("message",onWindowMessage)}};return callableFrame}var hasOwn=atob.call.bind({}.hasOwnProperty);function parseFunction(input){for(var strFunc=input+"",m;m=/\/\*[^]*?\*\/|\/\/.*/g.exec(strFunc);){var STR_BEFORE=strFunc.slice(0,m.index);if(/[\{"'`]/.test(STR_BEFORE))break;strFunc=STR_BEFORE+" "+strFunc.slice(m.index+m[0].length)}var input=/^\s*async\b/.test(strFunc),IS_GENERATOR=(input&&(strFunc=strFunc.replace("async","")),/^\s*(?:function\s*)?\*/.test(strFunc)),ARROW_MATCH=(IS_GENERATOR&&(strFunc=strFunc.replace(/(?:\bfunction\s*)?\*/,"")),/\s*=>\s*/.exec(strFunc)),INDEX_OF_FUNC_START=strFunc.search(/\)\s*\{/),INDEX_OF_FUNC_START=ARROW_MATCH&&(ARROW_MATCH.index<INDEX_OF_FUNC_START||INDEX_OF_FUNC_START<0),parameters,ARROW_MATCH,STR_BEFORE,ARROW_MATCH,parameters,ARROW_MATCH;return ARROW_MATCH=INDEX_OF_FUNC_START?(STR_BEFORE=strFunc.slice(0,ARROW_MATCH.index),ARROW_MATCH=strFunc.slice(ARROW_MATCH.index+ARROW_MATCH[0].length),parameters=(/\S+(?:\s*,\s*\S+)*/.exec(STR_BEFORE.replace(/[()]/g," "))??[])[0],/^\{/.test(ARROW_MATCH)?ARROW_MATCH.replace(/^\{|\}\s*$/g,""):"return "+ARROW_MATCH):(parameters=(/\(([^\)]*)\)/.exec(strFunc)??[])[1],(/\{([^]*)\}/.exec(strFunc)??[])[1]),{isAsync:input,isGenerator:IS_GENERATOR,isArrow:INDEX_OF_FUNC_START,parameters:parameters,body:ARROW_MATCH}}return createCallableFrame.parseFunction=parseFunction,createCallableFrame}();window.YourJSBox||(window.YourJSBox=YourJSBox);const currentScript=document.currentScript;currentScript&&!document.head?.contains(currentScript)&&createConsoleFromScript(currentScript)})();
9
+ `}function escapeHtmlAttribute(e){return(""+e).replace(/[&"<>]/g,e=>`&#${e.charCodeAt(0)};`)}function unindentMin(e,t){var i=(t=Object(t)).tabSize??4,t=t.trim??!0;if(e=e.replace(/\t/g," ".repeat(i)),!/(^|[\r\n])\S/.test(e)){const t=/(^|[\r\n])((?:(?!\r|\n)\s)+)(?=(\S)?)/g;let i=1/0;for(let s;s=t.exec(e);)s[3]&&(i=Math.min(i,s[2].length));e=e.replace(t,(e,t,s)=>t+s.slice(i))}return t?e.replace(/^(\s*[\r\n]+)+|\s+$/g,""):e}function sanitizeDescription(e){return{typeName:""+(e=Object(e)).typeName,isPrimitive:!!e.isPrimitive,parts:Array.from(e.parts??[],e=>[/^[a-z]+$/.test(Object(e)[0])?e[0]:"text",""+Object(e)[1]]),...sanitizeEntries(e),...null!=e.entriesArePropertyKeys?{entriesArePropertyKeys:!!e.entriesArePropertyKeys}:{}}}function sanitizeEntries(e){e=Object(e);var t={};for(const i of["entries","protoEntries"])Array.isArray(e[i])&&(t[i]=e[i].map(e=>[""+Object(e)[0],sanitizeDescription(Object(e)[1]),!1!==Object(e)[2]]));return t}function appendLog({logId:e,key:t,descriptions:i,table:s,groupIds:o,groupId:r,isCollapsed:n,stack:a}){t=""+t,mountedApp.displays.push({type:"log",key:t,name:"result"===t?"Result":"console."+t,descriptions:Array.from(i,sanitizeDescription),table:s?{headers:Array.from(s.headers,e=>""+e),rows:Array.from(s.rows,e=>({index:""+e.index,cells:Array.from(e.cells,e=>e&&sanitizeDescription(e))}))}:null,groupIds:Array.from(o??[],e=>""+e),groupId:null!=r?""+r:null,isCollapsed:!!n,stack:null!=a?""+a:null,logId:""+e})}function appendError({message:e,line:t,column:i}){mountedApp.displays.push({type:"error",message:""+e,line:+t,column:+i})}function updateDescriptionFor(e,t){const i=(e=Array.from(e)).shift(),s=mountedApp.displays.find(e=>"log"===e.type&&e.logId===i);let o=s?.descriptions[toIndex(e.shift())];for(let t=0;o&&t<e.length;t+=2){const i=e[t];if("entries"!==i&&"protoEntries"!==i)return;o=o[i]?.[toIndex(e[t+1])]?.[1]}if(o&&(Object.assign(o,sanitizeEntries(t)),o.entriesArePropertyKeys=!!Object(t).entriesArePropertyKeys,Array.isArray(Object(t).parts))){const{typeName:e,isPrimitive:i,parts:s}=sanitizeDescription(t);Object.assign(o,{typeName:e,isPrimitive:i,parts:s})}}function onValueJson(e){var{requestId:e,json:i,circularCount:s,error:o}=Object(e),r=jsonRequests.get(""+e);r&&(jsonRequests.delete(""+e),r({json:null!=i?""+i:null,circularCount:+s||0,error:null!=o?""+o:null}))}const jsonRequests=new Map;function onStoredAsGlobal(e){mountedApp.displays.push({type:"notice",message:"Stored as the global variable "+e})}function onCodeRan(){mountedApp.runningCount=Math.max(0,mountedApp.runningCount-1),mountedApp.runHiddenGroups()}function setPoppedOut(e,t){mountedApp.isPoppedOut=e,t&&mountedApp.restoreState(t)}function popIn(){mountedApp.bringBack()}function onPopOutFailed(){mountedApp.displays.push({type:"notice",message:"The pop-out window was blocked by the browser. Allow pop-ups for this site and try again."})}function clearDisplays(){mountedApp.displays=[{type:"notice",message:"Console was cleared"}]}function toIndex(e){return Number.isInteger(e)&&0<=e?e:void 0}},jsUrls:[libraryUrl("vue","dist/vue.global.prod.js"),libraryUrl("ace-builds","src-noconflict/ace.js"),libraryUrl("prismjs","components/prism-core.min.js"),libraryUrl("prismjs","plugins/autoloader/prism-autoloader.min.js"),libraryUrl("prismjs","plugins/match-braces/prism-match-braces.min.js"),libraryUrl("acorn","dist/acorn.js"),..."typescript"==language?[libraryUrl("@babel/standalone","babel.min.js")]:[]],cssUrls:["data:text/css,"+encodeURIComponent(VIEWER_IFRAME_CSS),libraryUrl("prism-themes","themes/prism-vsc-dark-plus.min.css"),libraryUrl("prismjs","plugins/match-braces/prism-match-braces.min.css")],head:targetWindow?'<meta charset="utf-8"><title>JS Box</title>':"",htmlAttributes:'data-theme="'+theme+'"',targetWindow:targetWindow,onMessage(message){relayMessage(message.data,{runner:runner,host:{apply:(func,args)=>hostFuncs[func](...args)}})},async onReady(){this.call("init",code,dataset,{runnerMode:runnerMode,blockType:blockType,language:language,showResults:showResults,importsUrl:importsUrl,packageInfo:PACKAGE_INFO,libraryVersions:LIBRARY_VERSIONS,isPopOut:!!targetWindow,popOutState:state??null})},body:VIEWER_IFRAME_HTML,style:{width:"100%",height:height||"100%",minHeight:"150px",border:0,display:"block"}})}addEventListener("pagehide",closePopOut),insert((inlineViewer=activeViewer=createViewer()).iframe);let isDestroyed=!1;function load(){runner||isDestroyed||(runner=("window"==runnerMode?createWindowRunner:createWorkerRunner)(sendToViewer),inlineViewer.load())}let loadObserver=null;return"eager"!==dataset.loading&&"function"==typeof window.IntersectionObserver?(loadObserver=new IntersectionObserver(entries=>{entries.some(entry=>entry.isIntersecting)&&(loadObserver.disconnect(),loadObserver=null,load())},{rootMargin:"200px"})).observe(inlineViewer.iframe):load(),{element:inlineViewer.iframe,destroy(){isDestroyed||(isDestroyed=!0,popOutWindow&&(clearInterval(popOutWatcher),popOutViewer.dispose(),popOutWindow.close(),popOutWindow=null),removeEventListener("pagehide",closePopOut),loadObserver?.disconnect(),runner?.destroy(),inlineViewer.dispose(),inlineViewer.iframe.remove())}}}function createConsoleFromScript(script){createConsole({code:script.textContent,dataset:JSON.parse(JSON.stringify(script.dataset)),insert:element=>script.parentNode.insertBefore(element,script)})}const PLACEMENTS={fill:(target,element)=>target.replaceChildren(element),append:(target,element)=>target.append(element),prepend:(target,element)=>target.prepend(element),replace:(target,element)=>target.replaceWith(element),before:(target,element)=>target.before(element),after:(target,element)=>target.after(element)},CONSOLE_OPTION_NAMES=["blockType","dividerOrient","hidePrefix","importsUrl","language","librariesUrl","loading","runner","showResults","theme"],YourJSBox=Object.freeze({version:PACKAGE_INFO.version,create(options){const{target,placement="fill",height,code=""}=options=Object(options),targetElement="string"==typeof target?document.querySelector(target):target;if(1!==targetElement?.nodeType)throw new TypeError("string"==typeof target?`YourJSBox.create(): no element matches the target ${JSON.stringify(target)}.`:"YourJSBox.create(): target must be an element or a CSS selector.");if(!Object.hasOwn(PLACEMENTS,placement))throw new TypeError(`YourJSBox.create(): placement must be one of ${Object.keys(PLACEMENTS).join(", ")}.`);var dataset={};for(const name of CONSOLE_OPTION_NAMES)null!=options[name]&&(dataset[name]=""+options[name]);return createConsole({code:""+code,dataset:dataset,height:"number"==typeof height?height+"px":null!=height?""+height:void 0,insert:element=>PLACEMENTS[placement](targetElement,element)})}});var createCallableFrame=function(){var IFRAME_SCRIPT_MESSAGE_CODE=parseFunction(function(){var HOST_WINDOW=window.opener||window.parent;function messageParent(message){HOST_WINDOW.postMessage(message,"*")}window.addEventListener("message",function(e){var data=e.data,func;e.source===HOST_WINDOW&&data&&/^[A-Za-z_$][\w$]*$/.test(data.funcName)&&Array.isArray(data.args)&&(func=eval(data.funcName),"function"==typeof func)&&func.apply(e,data.args)})}).body;function createCallableFrame(options){var jsCode=options.jsCode,onMessage=options.onMessage,onReady=options.onReady,style=options.style,isReady,READY_ID=Math.random()+""+Math.random(),jsCode=["(function(){",IFRAME_SCRIPT_MESSAGE_CODE,"var applyParent, callParent;","(function(READY_ID){",parseFunction(function(){applyParent=function(funcName,args){HOST_WINDOW.postMessage({funcName:funcName,args:args,id:READY_ID},"*")},callParent=function(funcName){HOST_WINDOW.postMessage({funcName:funcName,args:Array.prototype.slice.call(arguments,1),id:READY_ID},"*")};var interval=setInterval(function(){/^(complete|interactive)$/.test(document.readyState)&&(clearInterval(interval),messageParent(READY_ID))},100)}).body,"})("+JSON.stringify(READY_ID)+");","function"!=typeof jsCode?jsCode||"":parseFunction(jsCode).body,"})();"].join("\n").replace(/<(?=\/script|!--)/gi,"\\x3C"),TARGET_WINDOW=options.targetWindow,IFRAME=TARGET_WINDOW?null:document.createElement("iframe");function getFrameWindow(){return TARGET_WINDOW||IFRAME.contentWindow}var HTML_CODE=["<!DOCTYPE html>","<html "+(options.htmlAttributes||"")+">","<head>",options.head||"",(options.cssUrls||[]).map(function(cssUrl){return'<link href="'+cssUrl+'" rel="stylesheet">'}).join("\n"),"</head>","<body>",options.body||"",(options.jsUrls||[]).map(function(jsUrl){return'<script src="'+jsUrl+'"><\/script>'}).join("\n"),"<script>"+jsCode+"<\/script>","</body>","</html>"].join("\n");if(TARGET_WINDOW?(TARGET_WINDOW.document.open(),TARGET_WINDOW.document.write(HTML_CODE),TARGET_WINDOW.document.close()):(IFRAME.setAttribute("allow","fullscreen"),options.deferLoad||(IFRAME.srcdoc=HTML_CODE)),style&&IFRAME)if("string"==typeof style)IFRAME.style.cssText=style;else for(var styleKey in style)hasOwn(style,styleKey)&&(IFRAME.style[styleKey]=style[styleKey]);function onWindowMessage(e){if(e.source===getFrameWindow()){var data=e.data,dataIsReadyId=READY_ID===data;if(isReady&&!dataIsReadyId)options.functions&&data.id===READY_ID&&hasOwn(options.functions,data.funcName)?options.functions[data.funcName].apply(callableFrame,data.args):"function"==typeof onMessage?onMessage.call(callableFrame,e):console.warn("Message sent from callable frame but no listener was set up.",e);else if(dataIsReadyId)for(isReady=!0,"function"==typeof onReady&&onReady.call(callableFrame,e);queuedMessages.length;)postToFrame(queuedMessages.shift());else console.warn("Message sent from callable frame prematurely:",e)}}addEventListener("message",onWindowMessage);var queuedMessages=[];function postToFrame(message){isReady?getFrameWindow().postMessage(message,"*"):queuedMessages.push(message)}var callableFrame={apply:function(funcName,args){postToFrame({funcName:funcName,args:args})},call:function(funcName){postToFrame({funcName:funcName,args:Array.prototype.slice.call(arguments,1)})},iframe:IFRAME,window:TARGET_WINDOW,load:function(){IFRAME&&!IFRAME.srcdoc&&(IFRAME.srcdoc=HTML_CODE)},dispose:function(){removeEventListener("message",onWindowMessage)}};return callableFrame}var hasOwn=atob.call.bind({}.hasOwnProperty);function parseFunction(input){for(var strFunc=input+"",m;m=/\/\*[^]*?\*\/|\/\/.*/g.exec(strFunc);){var STR_BEFORE=strFunc.slice(0,m.index);if(/[\{"'`]/.test(STR_BEFORE))break;strFunc=STR_BEFORE+" "+strFunc.slice(m.index+m[0].length)}var input=/^\s*async\b/.test(strFunc),IS_GENERATOR=(input&&(strFunc=strFunc.replace("async","")),/^\s*(?:function\s*)?\*/.test(strFunc)),ARROW_MATCH=(IS_GENERATOR&&(strFunc=strFunc.replace(/(?:\bfunction\s*)?\*/,"")),/\s*=>\s*/.exec(strFunc)),INDEX_OF_FUNC_START=strFunc.search(/\)\s*\{/),INDEX_OF_FUNC_START=ARROW_MATCH&&(ARROW_MATCH.index<INDEX_OF_FUNC_START||INDEX_OF_FUNC_START<0),parameters,ARROW_MATCH,STR_BEFORE,ARROW_MATCH,parameters,ARROW_MATCH;return ARROW_MATCH=INDEX_OF_FUNC_START?(STR_BEFORE=strFunc.slice(0,ARROW_MATCH.index),ARROW_MATCH=strFunc.slice(ARROW_MATCH.index+ARROW_MATCH[0].length),parameters=(/\S+(?:\s*,\s*\S+)*/.exec(STR_BEFORE.replace(/[()]/g," "))??[])[0],/^\{/.test(ARROW_MATCH)?ARROW_MATCH.replace(/^\{|\}\s*$/g,""):"return "+ARROW_MATCH):(parameters=(/\(([^\)]*)\)/.exec(strFunc)??[])[1],(/\{([^]*)\}/.exec(strFunc)??[])[1]),{isAsync:input,isGenerator:IS_GENERATOR,isArrow:INDEX_OF_FUNC_START,parameters:parameters,body:ARROW_MATCH}}return createCallableFrame.parseFunction=parseFunction,createCallableFrame}();window.YourJSBox||(window.YourJSBox=YourJSBox);const currentScript=document.currentScript;currentScript&&!document.head?.contains(currentScript)&&createConsoleFromScript(currentScript)})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yourjs-box",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "A simple way to embed a JavaScript console on your website.",
5
5
  "unpkg": "dist/yourjs-box.min.js",
6
6
  "jsdelivr": "dist/yourjs-box.min.js",
@@ -13,6 +13,7 @@
13
13
  "start": "gulp",
14
14
  "test": "npm run build && node test/run.js",
15
15
  "release": "node scripts/release.js",
16
+ "record-demo": "node scripts/record-demo.js",
16
17
  "purge-cdn": "node scripts/purge-cdn.js",
17
18
  "version": "npm run build && git add dist",
18
19
  "prepublishOnly": "npm run build"