yourjs-box 1.10.0 → 1.11.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
@@ -101,23 +101,28 @@ objects and arrays) for a menu with:
101
101
  - **Refresh** (for objects, arrays, etc.), which shows the value as it is now
102
102
  if the code has changed it. Anything that was expanded stays expanded.
103
103
 
104
- ### Attributes
105
-
106
- | Attribute | Description |
107
- | --- | --- |
108
- | `data-block-type` | `"classic"` (default) runs each block like a regular `<script>` so top-level declarations are shared between blocks. `"module"` runs each block like a `<script type="module">`. See below. |
109
- | `data-language` | `"javascript"` (default) or `"typescript"`. See "TypeScript" below. |
110
- | `data-show-results` | `"false"` stops the value of the last expression in each block from being shown. |
111
- | `data-imports-url` | Where packages imported by name are loaded from. See "Importing Packages" below. |
112
- | `data-libraries-url` | Where to load Vue, Ace, Prism, Acorn and Babel from. See "Self-Hosting the Libraries" below. |
113
- | `data-runner` | `"worker"` (default) runs the code in a Web Worker. `"window"` runs it directly in the page. See below. |
114
- | `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. |
115
- | `data-hide-empty-output` | `"true"` (default) only shows the editor until there is something in the output (eg. once code is run). The output then stays (even after Clear) until the console is reset. `"false"` always shows the output. |
116
- | `data-hide-prefix` | Any block whose header starts with this prefix is hidden. See below. |
117
- | `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. |
118
- | `data-rulers` | The columns where lines are shown in the editor, eg. `"80, 120"`. Defaults to `"80"` and `""` shows none. |
119
- | `data-theme` | `"light"` or `"dark"`. Defaults to following the system's color scheme like the browser's dev tools. |
120
- | `data-word-wrap` | `"true"` wraps long lines in the editor instead of scrolling sideways. |
104
+ ### Options
105
+
106
+ Each option can be set with a `data-*` attribute on the script tag or, with
107
+ the [JavaScript API](#javascript-api), as an option of `YourJSBox.create()` or
108
+ `YourJSBox.from()`. Attribute values are always strings, while the API also
109
+ takes booleans for the true/false options and an array for `rulers`.
110
+
111
+ | Attribute | API option | Default | Description |
112
+ | --- | --- | --- | --- |
113
+ | `data-runner` | `runner` | `"worker"` | `"worker"` runs the code in a Web Worker. `"window"` runs it directly in the page. See "Where Code Runs" below. |
114
+ | `data-block-type` | `blockType` | `"classic"` | `"classic"` runs each block like a regular `<script>` so top-level declarations are shared between blocks. `"module"` runs each block like a `<script type="module">`. See "Module Blocks" below. |
115
+ | `data-language` | `language` | `"javascript"` | `"javascript"` or `"typescript"`. See "TypeScript" below. |
116
+ | `data-show-results` | `showResults` | `"true"` | `"false"` stops the value of the last expression in each block from being shown. See "Results" below. |
117
+ | `data-hide-prefix` | `hidePrefix` | None | Any block whose header starts with this prefix is hidden but still runs. See "Hidden Code" below. |
118
+ | `data-hide-empty-output` | `hideEmptyOutput` | `"true"` | `"true"` only shows the editor until there is something in the output (eg. once code is run). The output then stays (even after Clear) until the console is reset. `"false"` always shows the output. |
119
+ | `data-divider-orient` | `dividerOrient` | Automatic | `"vertical"` puts the editor beside the output and `"horizontal"` puts it below. If not given, the editor is beside the output unless the console is narrower than 600px. |
120
+ | `data-theme` | `theme` | The system's | `"light"` or `"dark"`. If not given, it follows the system's color scheme like the browser's dev tools. |
121
+ | `data-word-wrap` | `wordWrap` | `"false"` | `"true"` wraps long lines in the editor instead of scrolling sideways. |
122
+ | `data-rulers` | `rulers` | `"80"` | The columns where lines are shown in the editor, eg. `"80, 120"` (or `[80, 120]` with the API). `""` shows none. |
123
+ | `data-loading` | `loading` | `"lazy"` | `"lazy"` 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. |
124
+ | `data-imports-url` | `importsUrl` | esm.sh | Where packages imported by name are loaded from. `""` turns this off. See "Importing Packages" below. |
125
+ | `data-libraries-url` | `librariesUrl` | unpkg | Where to load Vue, Ace, Prism, Acorn and Babel from. See "Self-Hosting the Libraries" below. |
121
126
 
122
127
  ### Results
123
128
 
@@ -299,7 +304,7 @@ box.destroy();
299
304
  `YourJSBox.create(options)` returns `{element, destroy}` where `element` is the
300
305
  console's IFRAME and `destroy()` removes it, stops its code and closes its
301
306
  pop-out window (in window mode it also restores the page's `console`
302
- functions). The options are:
307
+ functions). Its own options are:
303
308
 
304
309
  | Option | Description |
305
310
  | --- | --- |
@@ -307,7 +312,8 @@ functions). The options are:
307
312
  | `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. |
308
313
  | `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. |
309
314
  | `code` | The code that the console starts with. |
310
- | `runner`, `blockType`, `language`, `showResults`, `hidePrefix`, `hideEmptyOutput`, `dividerOrient`, `theme`, `wordWrap`, `rulers`, `importsUrl`, `librariesUrl`, `loading` | The same as the `data-*` attributes above. `wordWrap`, `hideEmptyOutput` and `showResults` can be booleans and `rulers` can be an array (eg. `[80, 120]`). |
315
+
316
+ It also takes every option in [Options](#options) (eg. `theme` or `wordWrap`).
311
317
 
312
318
  `YourJSBox.from(elements, options)` turns existing elements (eg. the code blocks
313
319
  in a page made from Markdown) into consoles that start with their code:
@@ -334,6 +340,15 @@ in a page made from Markdown) into consoles that start with their code:
334
340
 
335
341
  `YourJSBox.version` is the version of YourJS Box that was loaded.
336
342
 
343
+ The package includes TypeScript types for `YourJSBox` (`dist/yourjs-box.d.ts`),
344
+ which also give you autocomplete in VS Code. Install the package (eg.
345
+ `npm install --save-dev yourjs-box`, even if the script itself comes from a
346
+ CDN) and add this line to the top of a TypeScript or JavaScript file:
347
+
348
+ ```js
349
+ /// <reference types="yourjs-box" />
350
+ ```
351
+
337
352
  ### Where Code Runs
338
353
 
339
354
  The console's interface is always in an IFRAME so that its styles and the
@@ -366,14 +381,16 @@ Install the development dependencies by running `npm install`.
366
381
  based browser). An internet connection is needed because the console loads
367
382
  its libraries from CDNs. Pass part of a test's name to run only matching
368
383
  tests (eg. `node test/run.js module`).
369
- - Before releasing, move the notes under **Unreleased** in
370
- [CHANGELOG.md](CHANGELOG.md) into a section for the new version.
384
+ - As you make changes, add notes for them under **Unreleased** in
385
+ [CHANGELOG.md](CHANGELOG.md).
371
386
  - `npm run release -- <patch|minor|major>` releases a new version: it checks
372
- that you're on an up to date, clean `main`, runs the tests, runs
373
- `npm version`, pushes `main` and then the tag (separately, because GitHub
374
- Pages doesn't always deploy when they are pushed together), publishes to npm
375
- and, once npm lists the new version, purges jsDelivr's cache. Add
376
- `--dry-run` to see what it would do or `--skip-tests` to skip the tests.
387
+ that you're on an up to date, clean `main` and that CHANGELOG.md has notes
388
+ under **Unreleased**, runs the tests, runs `npm version` (which also moves
389
+ those notes into a dated section for the new version), pushes `main` and then
390
+ the tag (separately, because GitHub Pages doesn't always deploy when they are
391
+ pushed together), publishes to npm and, once npm lists the new version,
392
+ purges jsDelivr's cache. Add `--dry-run` to see what it would do or
393
+ `--skip-tests` to skip the tests.
377
394
  - `npm run record-demo` records `demo.gif` (shown at the top of this README)
378
395
  from the built files. It needs [ffmpeg](https://ffmpeg.org/).
379
396
  - `npm run og-image` makes `og-image.png` (the picture shown when the landing
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Types for the `YourJSBox` global that loading YourJS Box provides. See
3
+ * https://github.com/westc/yourjs-box#javascript-api for more details.
4
+ *
5
+ * Use them in TypeScript (or in JavaScript checked by VS Code) with:
6
+ * /// <reference types="yourjs-box" />
7
+ */
8
+
9
+ declare namespace YourJSBox {
10
+ /**
11
+ * The options that can also be set with the `data-*` attributes of a script
12
+ * tag (eg. `wordWrap` is the same as `data-word-wrap`).
13
+ */
14
+ interface ConsoleOptions {
15
+ /**
16
+ * `"worker"` (default) runs the code in a Web Worker. `"window"` runs it
17
+ * directly in the page.
18
+ */
19
+ runner?: 'worker' | 'window';
20
+ /**
21
+ * `"classic"` (default) runs each block like a regular `<script>` so
22
+ * top-level declarations are shared between blocks. `"module"` runs each
23
+ * block like a `<script type="module">`.
24
+ */
25
+ blockType?: 'classic' | 'module';
26
+ /** `"javascript"` (default) or `"typescript"`. */
27
+ language?: 'javascript' | 'typescript';
28
+ /**
29
+ * Whether the value of the last expression in each block is shown.
30
+ * Defaults to `true`.
31
+ */
32
+ showResults?: boolean | 'true' | 'false';
33
+ /** Any block whose header starts with this prefix is hidden but still runs. */
34
+ hidePrefix?: string;
35
+ /**
36
+ * Whether only the editor is shown until there is something in the
37
+ * output. Defaults to `true`.
38
+ */
39
+ hideEmptyOutput?: boolean | 'true' | 'false';
40
+ /**
41
+ * `"vertical"` puts the editor beside the output and `"horizontal"` puts
42
+ * it below. If not given, the editor is beside the output unless the
43
+ * console is narrower than 600px.
44
+ */
45
+ dividerOrient?: 'vertical' | 'horizontal';
46
+ /** If not given, the theme follows the system's color scheme. */
47
+ theme?: 'light' | 'dark';
48
+ /** Whether long lines wrap in the editor. Defaults to `false`. */
49
+ wordWrap?: boolean | 'true' | 'false';
50
+ /**
51
+ * The columns where lines are shown in the editor (eg. `[80, 120]` or
52
+ * `"80, 120"`). Defaults to `80` and `""` (or `[]`) shows none.
53
+ */
54
+ rulers?: number | number[] | string;
55
+ /**
56
+ * `"lazy"` (default) waits to load the console until it is about to be
57
+ * scrolled into view. `"eager"` loads it right away.
58
+ */
59
+ loading?: 'lazy' | 'eager';
60
+ /**
61
+ * Where packages imported by name are loaded from, where `{specifier}` is
62
+ * replaced by the package (eg. `"https://esm.sh/{specifier}"`, which is
63
+ * the default). `""` turns this off.
64
+ */
65
+ importsUrl?: string;
66
+ /**
67
+ * Where to load Vue, Ace, Prism, Acorn and Babel from, where `{name}` and
68
+ * `{version}` are replaced by each library's name and version (eg.
69
+ * `"/node_modules/{name}/"`). Defaults to unpkg.
70
+ */
71
+ librariesUrl?: string;
72
+ }
73
+
74
+ /** Where a console goes relative to its target. */
75
+ type Placement = 'fill' | 'append' | 'prepend' | 'replace' | 'before' | 'after';
76
+
77
+ interface CreateOptions extends ConsoleOptions {
78
+ /** The element (or a CSS selector for it) that the console is placed relative to. */
79
+ target: string | Element;
80
+ /**
81
+ * `"fill"` (default) replaces the target's contents, `"append"` and
82
+ * `"prepend"` add the console inside of the target, `"replace"` replaces
83
+ * the target itself and `"before"` and `"after"` add it next to the target.
84
+ */
85
+ placement?: Placement;
86
+ /**
87
+ * The CSS height of the console (a number is treated as pixels).
88
+ * Defaults to `"100%"`. It is never less than 150px.
89
+ */
90
+ height?: string | number;
91
+ /** The code that the console starts with. */
92
+ code?: string;
93
+ }
94
+
95
+ interface FromOptions extends ConsoleOptions {
96
+ /** Defaults to `"replace"`. */
97
+ placement?: Placement;
98
+ /**
99
+ * The CSS height of each console (a number is treated as pixels).
100
+ * Defaults to a height that fits the code (from 250px to 600px).
101
+ */
102
+ height?: string | number;
103
+ }
104
+
105
+ /** A console that was created. */
106
+ interface Box {
107
+ /** The console's IFRAME. */
108
+ readonly element: HTMLIFrameElement;
109
+ /**
110
+ * Removes the console, stops its code and closes its pop-out window (in
111
+ * window mode it also restores the page's `console` functions). For a
112
+ * console made by `from()` that replaced its element, the element is put
113
+ * back.
114
+ */
115
+ destroy(): void;
116
+ }
117
+ }
118
+
119
+ declare const YourJSBox: {
120
+ /** The version of YourJS Box that was loaded (eg. `"1.10.0"`). */
121
+ readonly version: string;
122
+ /**
123
+ * Creates a console.
124
+ * @throws {TypeError} If the target or the placement isn't valid.
125
+ */
126
+ create(options: YourJSBox.CreateOptions): YourJSBox.Box;
127
+ /**
128
+ * Turns existing elements (eg. the code blocks in a page made from Markdown)
129
+ * into consoles that start with their code. The `data-*` attributes of each
130
+ * element override `options` and a `language-ts` class turns on TypeScript.
131
+ * @param elements
132
+ * A CSS selector, an element or a list of elements (eg. a `NodeList`).
133
+ * @returns The consoles in the same order as the elements.
134
+ */
135
+ from(
136
+ elements: string | Element | ArrayLike<Element> | Iterable<Element>,
137
+ options?: YourJSBox.FromOptions
138
+ ): YourJSBox.Box[];
139
+ };
140
+
141
+ interface Window {
142
+ YourJSBox: typeof YourJSBox;
143
+ }
@@ -1,4 +1,4 @@
1
- /*! yourjs-box v1.10.0 | (c) 2023-present Chris West | MIT License | https://github.com/westc/yourjs-box */
1
+ /*! yourjs-box v1.11.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.10.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.11.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}
@@ -1,4 +1,4 @@
1
- /*! yourjs-box v1.10.0 | (c) 2023-present Chris West | MIT License | https://github.com/westc/yourjs-box */
1
+ /*! yourjs-box v1.11.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.10.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.11.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}
@@ -1,5 +1,5 @@
1
- /*! yourjs-box v1.10.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}.svg-defs{height:0;position:absolute;width:0}#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)}#main.is-output-hidden{grid-template-columns:1fr;grid-template-rows:1fr}#main.is-output-hidden>#displays,#main.is-output-hidden>.divider{display:none}.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{flex:none;height:18px;width:18px}.logo-text{font-size:14px;white-space:nowrap}@media (max-width:440px){#bottomNav .logo-text{display:none}}.logo-your{font-weight:400;opacity:.8}.logo-large{gap:12px}.logo-large>.logo-mark{filter:drop-shadow(0 6px 12px rgb(0 0 0 / .18));height:56px;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{height:40px;width:40px}.logo-medium>.logo-text{display:none}.about-name{font-size:17px;font-weight:700}.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-shortcut{color:var(--muted-text);font-size:11px;margin-left:auto;padding-left:16px}.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}.console-row>.row-icon.repeat-count{background-color:var(--null);border-radius:7px;box-sizing:border-box;color:var(--console-bg);font-family:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;font-size:10px;height:14px;left:calc(3px + var(--depth,0) * 16px);line-height:14px;min-width:16px;padding:0 4px;text-align:center;top:3px}.log-warn>.row-icon.repeat-count{background-color:var(--warn-icon)}.log-assert>.row-icon.repeat-count,.log-error>.row-icon.repeat-count{background-color:var(--error-icon)}.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}.row-content>.js-value+.js-value.is-joined{margin-left:0}.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.10.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='<svg class="svg-defs" aria-hidden="true">\x3c!-- The logo: an open box whose front is the yellow JS square. --\x3e<symbol id="logo-mark" viewBox="0 0 32 32"><polygon points="1,10 8,3 31,3 24,10" fill="#4a4a4a"/><polygon points="8,3 31,3 29,5 10,5" fill="#2e2e2e"/><polygon points="24,10 31,3 31,24 24,31" fill="#c7b000"/><rect x="1" y="10" width="23" height="21" rx="1.5" fill="#f7df1e"/><text x="22" y="28.5" text-anchor="end" font-size="11.5" font-weight="800" letter-spacing="-0.3" fill="#1a1a1a">JS</text></symbol></svg><div id="splash" aria-label="Loading"><div class="splash-content"><span class="logo logo-large"><svg class="logo-mark"><use href="#logo-mark"/></svg><span class="logo-text"><span class="logo-your">Your</span>JS 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">YourJS 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.count > 1" class="row-icon repeat-count">{{ display.count }}</span> <span v-else-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" :class="description.isJoined ? \'is-joined\' : \'\'" :style="description.style" :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 v-if="display.count > 1" class="row-icon repeat-count">{{ display.count }}</span> <span v-else 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)" :word-wrap="wordWrap" :rulers="rulers" @key-combo="onEditorKeyCombo" @history-key="onEditorHistoryKey" height="100%"></ace-editor></div></div><div id="bottomNav"><div class="brand"><button class="logo-button" title="About YourJS Box" @click="openAbout(\'about\')"><span class="logo"><svg class="logo-mark"><use href="#logo-mark"/></svg><span class="logo-text"><span class="logo-your">Your</span>JS 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"><button class="menu-item" role="menuitem" :disabled="!canRunCode" @click="closeMenu(); runAll()"><span class="menu-icon"><icon name="runAll"></icon></span>Run all blocks<span class="menu-shortcut">{{ modKey === \'Ctrl\' ? \'Ctrl+Shift+Enter\' : \'&#8679;&#8984;&#8629;\' }}</span></button><div class="menu-separator"></div><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 YourJS 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"><svg class="logo-mark"><use href="#logo-mark"/></svg><span class="logo-text"><span class="logo-your">Your</span>JS 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 YourJS 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"><svg class="logo-mark"><use href="#logo-mark"/></svg><span class="logo-text"><span class="logo-your">Your</span>JS Box</span></span><div><div class="about-name">YourJS Box</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>{{ modKey }}</kbd> + <kbd>Shift</kbd> + <kbd>Enter</kbd></dt><dd>Run all of the remaining blocks</dd><dt><kbd>Ctrl</kbd> + <kbd>L</kbd></dt><dd>Clear the console</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,l;const a={},u={},f={},p={};let d=[],g=0;const h="yourjs-box.result."+Math.random().toString(36).slice(2),y=(globalThis[Symbol.for(h)]=x,[]);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 m(e,n),t.apply(this,arguments)};console[e]=n,y.push({key:e,original:t,wrapper:n})}}function m(t,n){var r=n.length&&void 0!==n[0]?""+n[0]:"default";if("clear"===t)Z(),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,$("count",[r+": "+f[r]]);else if("countReset"===t)Object.hasOwn(f,r)?f[r]=0:$("warn",[`Count for '${r}' does not exist`]);else if("time"===t)Object.hasOwn(p,r)?$("warn",[`Timer '${r}' already exists`]):p[r]=performance.now();else if("timeLog"===t||"timeEnd"===t){if(!Object.hasOwn(p,r))return $("warn",[`Timer '${r}' does not exist`]);const e=performance.now()-p[r];"timeEnd"===t&&delete p[r],$(t,[r+`: ${+e.toFixed(3)} ms`,..."timeLog"===t?n.slice(1):[]])}else if("trace"===t){const e=S((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 if("table"===t||"dir"===t||"dirxml"===t){const e="table"===t?k(n[0],n[1]):null;$(t,e?n.slice(0,1):n,{table:e})}else b(t,n)}function b(e,t,n){var{values:t,formats:o}=v(t);$(e,t,n,0,o)}function v(e){var[t,...n]=e;if("string"!=typeof t||!t.includes("%"))return{values:e,formats:[]};const r=[],o=[];let s="",i="";var c=(e,t)=>{s&&(r.push(s),o.push({style:i,isJoined:1<r.length}),s=""),null!=t&&(r.push(e),o.push({depth:t,style:i,isJoined:1<r.length}))},l=/%([sdifoOc%])/g;let a=0;for(let e;e=l.exec(t);){const r=e[1];if(s+=t.slice(a,e.index),a=l.lastIndex,"%"===r)s+="%";else if(n.length){const o=n.shift();"c"===r?(c(),i=""+o):"d"===r||"i"===r?s+="symbol"==typeof o?"NaN":parseInt(o,10):"f"===r?s+="symbol"==typeof o?"NaN":parseFloat(o):"s"===r&&(null===o||"object"!=typeof o&&"function"!=typeof o)?s+="bigint"==typeof o?o+"n":String(o):c(o,"o"===r&&"string"==typeof o?1:0)}else s+=e[0]}return s+=t.slice(a),c(),{values:[...r,...n],formats:o}}function $(t,n,r,i=0,c=[]){var l=""+ ++s;o[l]=n.map((e,t)=>({...D(e,c[t]?.depth??i),value:e})),e({target:"viewer",func:"appendLog",args:[{logId:l,key:t,descriptions:o[l].map((e,t)=>{var{style:t,isJoined:r}=c[t]??{};return{...A(["value"],e),...t?{style:t}:{},...r?{isJoined:r}:{}}}),groupIds:d.slice(),...r}]})}function x(e){void 0!==e&&$("result",[e],{},"string"==typeof e?1:0)}function j(e){E(void 0!==e.error?e.error:e.message)}function O(e){E(e.reason,!0)}function w(){removeEventListener("error",j),removeEventListener("unhandledrejection",O),delete globalThis[Symbol.for(h)];for(var{key:e,original:t,wrapper:n}of y)console[e]===n&&(console[e]=t);Z()}function E(t,n){var r="classic"===l&&"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.11.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}.svg-defs{height:0;position:absolute;width:0}#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)}#main.is-output-hidden{grid-template-columns:1fr;grid-template-rows:1fr}#main.is-output-hidden>#displays,#main.is-output-hidden>.divider{display:none}.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{flex:none;height:18px;width:18px}.logo-text{font-size:14px;white-space:nowrap}@media (max-width:440px){#bottomNav .logo-text{display:none}}.logo-your{font-weight:400;opacity:.8}.logo-large{gap:12px}.logo-large>.logo-mark{filter:drop-shadow(0 6px 12px rgb(0 0 0 / .18));height:56px;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{height:40px;width:40px}.logo-medium>.logo-text{display:none}.about-name{font-size:17px;font-weight:700}.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-shortcut{color:var(--muted-text);font-size:11px;margin-left:auto;padding-left:16px}.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}.console-row>.row-icon.repeat-count{background-color:var(--null);border-radius:7px;box-sizing:border-box;color:var(--console-bg);font-family:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;font-size:10px;height:14px;left:calc(3px + var(--depth,0) * 16px);line-height:14px;min-width:16px;padding:0 4px;text-align:center;top:3px}.log-warn>.row-icon.repeat-count{background-color:var(--warn-icon)}.log-assert>.row-icon.repeat-count,.log-error>.row-icon.repeat-count{background-color:var(--error-icon)}.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}.row-content>.js-value+.js-value.is-joined{margin-left:0}.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.11.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='<svg class="svg-defs" aria-hidden="true">\x3c!-- The logo: an open box whose front is the yellow JS square. --\x3e<symbol id="logo-mark" viewBox="0 0 32 32"><polygon points="1,10 8,3 31,3 24,10" fill="#4a4a4a"/><polygon points="8,3 31,3 29,5 10,5" fill="#2e2e2e"/><polygon points="24,10 31,3 31,24 24,31" fill="#c7b000"/><rect x="1" y="10" width="23" height="21" rx="1.5" fill="#f7df1e"/><text x="22" y="28.5" text-anchor="end" font-size="11.5" font-weight="800" letter-spacing="-0.3" fill="#1a1a1a">JS</text></symbol></svg><div id="splash" aria-label="Loading"><div class="splash-content"><span class="logo logo-large"><svg class="logo-mark"><use href="#logo-mark"/></svg><span class="logo-text"><span class="logo-your">Your</span>JS 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">YourJS 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.count > 1" class="row-icon repeat-count">{{ display.count }}</span> <span v-else-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" :class="description.isJoined ? \'is-joined\' : \'\'" :style="description.style" :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 v-if="display.count > 1" class="row-icon repeat-count">{{ display.count }}</span> <span v-else 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)" :word-wrap="wordWrap" :rulers="rulers" @key-combo="onEditorKeyCombo" @history-key="onEditorHistoryKey" height="100%"></ace-editor></div></div><div id="bottomNav"><div class="brand"><button class="logo-button" title="About YourJS Box" @click="openAbout(\'about\')"><span class="logo"><svg class="logo-mark"><use href="#logo-mark"/></svg><span class="logo-text"><span class="logo-your">Your</span>JS 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"><button class="menu-item" role="menuitem" :disabled="!canRunCode" @click="closeMenu(); runAll()"><span class="menu-icon"><icon name="runAll"></icon></span>Run all blocks<span class="menu-shortcut">{{ modKey === \'Ctrl\' ? \'Ctrl+Shift+Enter\' : \'&#8679;&#8984;&#8629;\' }}</span></button><div class="menu-separator"></div><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 YourJS 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"><svg class="logo-mark"><use href="#logo-mark"/></svg><span class="logo-text"><span class="logo-your">Your</span>JS 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 YourJS 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"><svg class="logo-mark"><use href="#logo-mark"/></svg><span class="logo-text"><span class="logo-your">Your</span>JS Box</span></span><div><div class="about-name">YourJS Box</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>{{ modKey }}</kbd> + <kbd>Shift</kbd> + <kbd>Enter</kbd></dt><dd>Run all of the remaining blocks</dd><dt><kbd>Ctrl</kbd> + <kbd>L</kbd></dt><dd>Clear the console</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,l;const a={},u={},f={},p={};let d=[],g=0;const h="yourjs-box.result."+Math.random().toString(36).slice(2),y=(globalThis[Symbol.for(h)]=x,[]);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 m(e,n),t.apply(this,arguments)};console[e]=n,y.push({key:e,original:t,wrapper:n})}}function m(t,n){var r=n.length&&void 0!==n[0]?""+n[0]:"default";if("clear"===t)Z(),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,$("count",[r+": "+f[r]]);else if("countReset"===t)Object.hasOwn(f,r)?f[r]=0:$("warn",[`Count for '${r}' does not exist`]);else if("time"===t)Object.hasOwn(p,r)?$("warn",[`Timer '${r}' already exists`]):p[r]=performance.now();else if("timeLog"===t||"timeEnd"===t){if(!Object.hasOwn(p,r))return $("warn",[`Timer '${r}' does not exist`]);const e=performance.now()-p[r];"timeEnd"===t&&delete p[r],$(t,[r+`: ${+e.toFixed(3)} ms`,..."timeLog"===t?n.slice(1):[]])}else if("trace"===t){const e=S((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 if("table"===t||"dir"===t||"dirxml"===t){const e="table"===t?k(n[0],n[1]):null;$(t,e?n.slice(0,1):n,{table:e})}else b(t,n)}function b(e,t,n){var{values:t,formats:o}=v(t);$(e,t,n,0,o)}function v(e){var[t,...n]=e;if("string"!=typeof t||!t.includes("%"))return{values:e,formats:[]};const r=[],o=[];let s="",i="";var c=(e,t)=>{s&&(r.push(s),o.push({style:i,isJoined:1<r.length}),s=""),null!=t&&(r.push(e),o.push({depth:t,style:i,isJoined:1<r.length}))},l=/%([sdifoOc%])/g;let a=0;for(let e;e=l.exec(t);){const r=e[1];if(s+=t.slice(a,e.index),a=l.lastIndex,"%"===r)s+="%";else if(n.length){const o=n.shift();"c"===r?(c(),i=""+o):"d"===r||"i"===r?s+="symbol"==typeof o?"NaN":parseInt(o,10):"f"===r?s+="symbol"==typeof o?"NaN":parseFloat(o):"s"===r&&(null===o||"object"!=typeof o&&"function"!=typeof o)?s+="bigint"==typeof o?o+"n":String(o):c(o,"o"===r&&"string"==typeof o?1:0)}else s+=e[0]}return s+=t.slice(a),c(),{values:[...r,...n],formats:o}}function $(t,n,r,i=0,c=[]){var l=""+ ++s;o[l]=n.map((e,t)=>({...D(e,c[t]?.depth??i),value:e})),e({target:"viewer",func:"appendLog",args:[{logId:l,key:t,descriptions:o[l].map((e,t)=>{var{style:t,isJoined:r}=c[t]??{};return{...A(["value"],e),...t?{style:t}:{},...r?{isJoined:r}:{}}}),groupIds:d.slice(),...r}]})}function x(e){void 0!==e&&$("result",[e],{},"string"==typeof e?1:0)}function j(e){E(void 0!==e.error?e.error:e.message)}function O(e){E(e.reason,!0)}function w(){removeEventListener("error",j),removeEventListener("unhandledrejection",O),delete globalThis[Symbol.for(h)];for(var{key:e,original:t,wrapper:n}of y)console[e]===n&&(console[e]=t);Z()}function E(t,n){var r="classic"===l&&"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 ")+S(t?.stack??""+(t?.message??t))+r}]})}function S(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=a[t];return o&&n===o.line&&r>o.column&&(r=Math.max(o.column,r-o.shift)),[n,r]=N(u[t],n,r),t+`:${n}:`+r})}function N(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 A(e,t){if(!t)return t=>A(e,t);var n={...t};for(const t of e)delete n[t];return n}function k(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)?D(t[e],2):null),...c?[n?D(r,2):null]:[]]}))}}function L(e){var t;return null==e?""+e:"object"==(t=typeof e)||"undefined"==t?Object.prototype.toString.call(e).slice(8,-1):t}function T(e,t){try{const t=Object.getPrototypeOf(e)?.constructor?.name;if(t&&"string"==typeof t)return t}catch(e){}return t}addEventListener("error",j),addEventListener("unhandledrejection",O);const C=5,R=100;function D(e,t=0,n=!1){var r=L(e),o="function"!==r&&r===r.toLowerCase(),s=void 0;return{typeName:r,isPrimitive:o,parts:n?[["text","Object"!==r?r:T(e,r)]]:J(e,t,r)}}function J(e,t,n=L(e)){if("string"===n)return t?[["string",M(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 U(e,t);try{return I(e,t,n)}catch(e){return[["text",n]]}}function M(e){var t=JSON.stringify(e);return e.includes("'")?t:`'${t.slice(1,-1).replace(/\\"/g,'"')}'`}function U(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 I(e,t,n){var r=T(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",M(e.data)]]:[["node",e.nodeName]];if(e instanceof Error)return[["text",t?e.name+": "+e.message:S(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,R)},(e,t)=>t),t,t=>s.push(...t in e?J(e[t],2):[["null","empty"]])),s.push(["text","]"])}else if("Map"===n||"Set"===n){const t=[...e].slice(0,R);s.push(["text",`${r}(${e.size}) {`]),i(t,e.size,e=>{"Map"===n?s.push(...J(e[0],2),["text"," => "],...J(e[1],2)):s.push(...J(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","{"],...J(e.valueOf(),2),["text","}"]):(s.push(["text","{"]),i(t.slice(0,C),t.length,t=>{var n=Object.getOwnPropertyDescriptor(e,t);s.push(["key",t],["text",": "],..."value"in n?J(n.value,2):[["text","(\u2026)"]])}),s.push(["text","}"]))}return s}function P(e,t=e){const n=L(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([J(t,2).map(e=>e[1]).join(""),D(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,D(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,D(i,1),s.enumerable]),o.push({value:i})}catch(e){}var l=Object.getPrototypeOf(e);null!==l&&(s.push(["[[Prototype]]",D(l,1,!0)]),i.push({value:l,receiver:t}))}return{entries:r,protoEntries:s,entriesArePropertyKeys:!c,$entries:o,$protoEntries:i}}async function V(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");a[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;l="module"===o?"module":"classic";try{if(p){const{message:e,line:t,column:n}=p;E({name:"SyntaxError",message:""+e,stack:`SyntaxError: ${e}
5
5
  at ${d}:${+t}:`+ +n})}else if("module"===o)await import("data:text/javascript;charset=utf-8,"+encodeURIComponent(r));else if("worker"===n)F(r);else{const e=document.createElement("script");e.textContent=r,document.head.appendChild(e),e.remove()}}catch(e){E(e)}l=void 0,e({target:"viewer",func:"onCodeRan",args:[]})}function F(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 z(e){G(e,!1)}function B(e){G(e,!0)}function G(t,n){var r=_(t),o,n;r&&(o=P(r.value,"receiver"in r?r.receiver:r.value),Object.assign(r,o),n=n?D(r.value,2<t.length?1:0,"protoEntries"===t[t.length-2]):{},e({target:"viewer",func:"updateDescriptionFor",args:[t,{...A(["$entries","$protoEntries"],o),...n}]}))}function _(e){let t=o;return e.forEach((e,n)=>{t=t?.[n&&n%2==0?"$"+e:e]}),t}function q(t,n){var t=_(t);let o;try{o=t?K(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 K(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 X(t){var t=_(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 Z(){for(const e of Object.keys(o))delete o[e];d=[]}return{clearLogs:Z,destroy:w,getValueAsJson:q,refreshDescription:B,runCode:V,sendDescriptionFor:z,storeAsGlobal:X}}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??"",r=matchMedia("(prefers-color-scheme: dark)"),o=unindentMin(e),{visibleCode:n,hiddenGroups:a}=extractHiddenGroups(o,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:o,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,isRunningAll:!1,dialog:null,isDisplaysScrolledToBottom:!0,forcedTheme:/^(light|dark)$/.test(t.theme)?t.theme:null,prefersDark:r.matches,runCount:0,jsCode:n,wordWrap:"true"===t.wordWrap,rulers:parseRulers(t.rulers),hideEmptyOutput:"false"!==t.hideEmptyOutput,hasShownOutput:!1,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 (Ctrl+L)",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) or all of the blocks (${l?"\u21e7\u2318":"Ctrl+Shift+"}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()},isOutputHidden(){return this.hideEmptyOutput&&!this.hasShownOutput&&!this.displays.length},mainElemClassNames(){return["vertical"===this.dividerOrient?"col-orient":"row-orient",this.isMovingDivider?"is-moving-divider":"",this.isOutputHidden?"is-output-hidden":""].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&&(e.shiftKey?this.runAll():this.runCode())},runAll(){this.canRunCode&&(this.isRunningAll=!0,this.runningCount||this.runCode())},onGroupRan(){this.runningCount=Math.max(0,this.runningCount-1),this.runHiddenGroups(),this.isRunningAll&&!this.runningCount&&(this.canRunCode?this.runCode():this.isRunningAll=!1)},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:o}=(!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:o}):{code:e.lines},{code:i,resultRange:l}=e.error?{code:"",resultRange:null}:prepareCode(e.code,{blockType:o,importsUrl:this.importsUrl,findResult:this.showResults&&!i});messageParent({target:"runner",func:"runCode",args:[i,{blockType:o,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.isRunningAll=!1,this.hasShownOutput=!1,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?"yourjs-box-code.ts":"yourjs-box-code.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]}),r=await s.createWritable();return await r.write(e),await r.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:"yourjs-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,hasShownOutput:this.hasShownOutput,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){return!e.altKey||e.ctrlKey||e.metaKey||"KeyH"!==e.code?!e.ctrlKey||e.altKey||e.metaKey||e.shiftKey||"KeyL"!==e.code?void("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(),void this.clearConsole()):(e.preventDefault(),e.stopPropagation(),void 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 r;if("function"==typeof window.showSaveFilePicker)try{r=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(r){const e=await r.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,o=t.width,t=t.height;return 100-100*Math.min(Math.max(.2,"vertical"===i?s/o: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"(e){e&&(this.hasShownOutput=!0),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),r.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","rulers","theme","width","wordWrap"],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)},wordWrap(e){this.editor.session.setUseWrapMode(!!e)},rulers(){this.updateRulers()},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),e.session.setUseWrapMode(!!this.wordWrap),this.rulers&&(e.setShowPrintMargin(!1),this.rulersLayer=Object.assign(document.createElement("div"),{className:"ace_layer ace_print-margin-layer"}),e.renderer.content.prepend(this.rulersLayer),e.renderer.on("afterRender",()=>this.updateRulers())),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:r,infoNotes:o,warningNotes:n}=(this.annotations=e.getSession().getAnnotations(),this);t!==JSON.stringify(r)&&this.$emit("changeErrorNotes",r),i!==JSON.stringify(o)&&this.$emit("changeInfoNotes",o),s!==JSON.stringify(n)&&this.$emit("changeWarningNotes",n)}),this.$refs.editor.addEventListener("keydown",t=>{var i="ArrowUp"===t.key,s,r,o,s;!i&&"ArrowDown"!==t.key||t.shiftKey||t.altKey||t.ctrlKey||t.metaKey||!e.selection.isEmpty()||({row:s,column:r}=e.getCursorPosition(),o=e.session.getLength()-1,(i?0===s&&0===r:s===o&&r===e.session.getLine(o).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)})},methods:{updateRulers(){const{rulersLayer:e,editor:t}=this;if(e){const{characterWidth:i,$padding:s}=t.renderer,r=Array.from(this.rulers??[]);for(;e.children.length>r.length;)e.lastChild.remove();for(;e.children.length<r.length;)e.append(Object.assign(document.createElement("div"),{className:"ace_print-margin"}));r.forEach((t,r)=>{e.children[r].style.left=Math.round(i*t+s)+"px"})}}},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>',runAll:'<svg viewBox="0 0 16 16"><path fill="currentColor" d="M1 2.5v11L7.5 8zM8 2.5v11L14.5 8z"/></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),r=s?t.replace(/^\/+\s*|\s*\\+$/g,""):t;return!e.length||s&&!i.canAppendHeader?e.push({headerLines:s?[r]:[],lines:s?[]:[t],allLines:[t],canAppendHeader:s}):(s?i.headerLines.push(r):(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 r of parseJSCodeGroups(e))parseGroupHeader(r.headerLines,t).isHidden?s.push({...r,runCount:i.length}):i.push(r);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 r=0,o=0;for(const t of s){const i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(t);r+=(31&i)<<o,32&i?o+=5:(e.push(1&r?-(r>>>1):r>>>1),r=o=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 r;try{r=acorn.parse(e,{ecmaVersion:"latest",sourceType:"module"===t?"module":"script",allowHashBang:!0})}catch(t){return{code:e,resultRange:null}}let o=null;if(s){const e=r.body[r.body.length-1];"ExpressionStatement"!==e?.type||e.directive||(o=[e.expression.start,e.expression.end])}const n=[];i&&walkAst(r,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 r=s.length-(i-t);o=o&&o.map(e=>e>=i?e+r:e)}return{code:e,resultRange:o}}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)?`// \\\\
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "yourjs-box",
3
- "version": "1.10.0",
3
+ "version": "1.11.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",
7
+ "types": "dist/yourjs-box.d.ts",
7
8
  "files": [
8
9
  "dist"
9
10
  ],
@@ -16,7 +17,7 @@
16
17
  "record-demo": "node scripts/record-demo.js",
17
18
  "og-image": "node scripts/make-og-image.js",
18
19
  "purge-cdn": "node scripts/purge-cdn.js",
19
- "version": "npm run build && git add dist",
20
+ "version": "npm run build && node scripts/update-changelog.js && git add dist CHANGELOG.md",
20
21
  "prepublishOnly": "npm run build"
21
22
  },
22
23
  "repository": {