numbl 0.4.3 → 0.4.5
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 +5 -1
- package/dist-cli/cli.js +10689 -8543
- package/dist-lib/graphics/figuresReducer.d.ts +14 -1
- package/dist-lib/graphics/types.d.ts +60 -0
- package/dist-lib/lib.js +24594 -22515
- package/dist-lib/numbl-core/executeCode.d.ts +10 -0
- package/dist-lib/numbl-core/executors/handleInline.d.ts +18 -2
- package/dist-lib/numbl-core/executors/jit/valueAdapter.d.ts +16 -9
- package/dist-lib/numbl-core/jit/compileSpecC.d.ts +7 -0
- package/dist-lib/numbl-core/jit/lowering/definiteAssign.d.ts +42 -0
- package/dist-lib/numbl-core/lexer/types.d.ts +62 -61
- package/dist-lib/numbl-core/native/ts-lapack-eig-complex.d.ts +32 -0
- package/dist-lib/numbl-core/runtime/plotBuiltinDispatch.d.ts +6 -0
- package/dist-lib/numbl-core/runtime/plotUtils.d.ts +55 -2
- package/dist-lib/numbl-core/runtime/runtime.d.ts +25 -0
- package/dist-lib/numbl-core/runtime/runtimePlot.d.ts +6 -0
- package/dist-lib/numbl-core/runtime/struct-access.d.ts +4 -0
- package/dist-lib/numbl-core/runtime/uihtmlSession.d.ts +40 -0
- package/dist-lib/numbl-core/version.d.ts +1 -1
- package/dist-plot-viewer/assets/index-CPiPZdGN.js +4504 -0
- package/dist-plot-viewer/index.html +1 -1
- package/dist-site-viewer/assets/index-Y_Z9U6zO.js +4826 -0
- package/dist-site-viewer/assets/numbl-worker-CdHI6Ort.js +12088 -0
- package/dist-site-viewer/index.html +1 -1
- package/dist-site-viewer/numbl-embed.js +131 -18
- package/package.json +1 -1
- package/dist-plot-viewer/assets/index-ClpZQuMR.js +0 -4426
- package/dist-site-viewer/assets/index-CgKjTQT7.js +0 -4748
- package/dist-site-viewer/assets/numbl-worker-DarsHbBe.js +0 -11993
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<title>numbl project</title>
|
|
8
8
|
<!-- numbl:base -->
|
|
9
9
|
<script src="./coi-serviceworker.js"></script>
|
|
10
|
-
<script type="module" crossorigin src="./assets/index-
|
|
10
|
+
<script type="module" crossorigin src="./assets/index-Y_Z9U6zO.js"></script>
|
|
11
11
|
<link rel="stylesheet" crossorigin href="./assets/index-D5YY8PKx.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
@@ -5,17 +5,65 @@ Usage:
|
|
|
5
5
|
<numbl-embed>
|
|
6
6
|
<iframe width="100%" height="500" frameborder="0"></iframe>
|
|
7
7
|
|
|
8
|
-
<script type="text/plain" class="
|
|
9
|
-
...
|
|
8
|
+
<script type="text/plain" class="numbl-script">
|
|
9
|
+
... numbl script ...
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
12
|
</numbl-embed>
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
Optional preamble: setup code that runs before the visible script on every Run
|
|
15
|
+
(e.g. installing a package with `mip load --install ...`). It is kept out of the
|
|
16
|
+
editor, and its console output is hidden behind a "Preparing…" message unless it
|
|
17
|
+
errors — in which case the output and error are shown. Override that message
|
|
18
|
+
per-embed with the `preparing-label` attribute (e.g. "Installing…").
|
|
19
|
+
|
|
20
|
+
<numbl-embed preparing-label="Installing…">
|
|
21
|
+
<iframe width="100%" height="500" frameborder="0"></iframe>
|
|
22
|
+
|
|
23
|
+
<script type="text/plain" class="numbl-preamble">
|
|
24
|
+
mip load --install owner/repo/package
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<script type="text/plain" class="numbl-script">
|
|
28
|
+
... numbl script ...
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
</numbl-embed>
|
|
32
|
+
|
|
33
|
+
The classes `matlab-script` / `matlab-preamble` are accepted as synonyms for
|
|
34
|
+
`numbl-script` / `numbl-preamble` (backward compatibility with older embeds).
|
|
35
|
+
|
|
36
|
+
You can also specify the script URL via attribute (a `numbl-preamble` block still
|
|
37
|
+
applies):
|
|
38
|
+
<numbl-embed script="relative-or-absolute-url-to-script">
|
|
16
39
|
<iframe width="100%" height="500" frameborder="0"></iframe>
|
|
17
40
|
</numbl-embed>
|
|
41
|
+
|
|
42
|
+
Lazy mode (recommended when many embeds share a page, e.g. documentation):
|
|
43
|
+
add the `lazy` attribute and the iframe is not loaded until the reader clicks
|
|
44
|
+
an "Edit & run" button. This keeps the page light — no worker, editor, or
|
|
45
|
+
package download boots until the reader asks for it. Customize the button text
|
|
46
|
+
with the `label` attribute.
|
|
47
|
+
|
|
48
|
+
<numbl-embed lazy label="▶ Edit & run this example"
|
|
49
|
+
script="https://example.com/snippet.m">
|
|
50
|
+
<iframe width="100%" height="560" frameborder="0"></iframe>
|
|
51
|
+
</numbl-embed>
|
|
18
52
|
*/
|
|
53
|
+
// Base64-encode a string as UTF-8. Plain btoa() throws on any character
|
|
54
|
+
// outside Latin-1 (e.g. an em dash or a Greek letter in a comment/title), so
|
|
55
|
+
// we go through the UTF-8 bytes. For pure-ASCII input this is byte-identical
|
|
56
|
+
// to btoa(), so it stays compatible with older /embed decoders.
|
|
57
|
+
function utf8ToBase64(text) {
|
|
58
|
+
const bytes = new TextEncoder().encode(text);
|
|
59
|
+
let binary = "";
|
|
60
|
+
const chunk = 0x8000;
|
|
61
|
+
for (let i = 0; i < bytes.length; i += chunk) {
|
|
62
|
+
binary += String.fromCharCode.apply(null, bytes.subarray(i, i + chunk));
|
|
63
|
+
}
|
|
64
|
+
return btoa(binary);
|
|
65
|
+
}
|
|
66
|
+
|
|
19
67
|
class NumblEmbed extends HTMLElement {
|
|
20
68
|
constructor() {
|
|
21
69
|
super();
|
|
@@ -23,19 +71,65 @@ class NumblEmbed extends HTMLElement {
|
|
|
23
71
|
|
|
24
72
|
connectedCallback() {
|
|
25
73
|
if (document.readyState === "loading") {
|
|
26
|
-
document.addEventListener("DOMContentLoaded", () => this.
|
|
74
|
+
document.addEventListener("DOMContentLoaded", () => this.setup());
|
|
27
75
|
} else {
|
|
28
|
-
this.
|
|
76
|
+
this.setup();
|
|
29
77
|
}
|
|
30
78
|
}
|
|
31
79
|
|
|
32
|
-
|
|
80
|
+
setup() {
|
|
33
81
|
this.iframe = this.querySelector("iframe");
|
|
34
82
|
if (!this.iframe) {
|
|
35
83
|
console.error("Missing iframe element in numbl-embed");
|
|
36
84
|
return;
|
|
37
85
|
}
|
|
38
86
|
|
|
87
|
+
// Lazy mode: defer all loading until the reader opts in by clicking.
|
|
88
|
+
if (this.hasAttribute("lazy")) {
|
|
89
|
+
this.renderActivateButton();
|
|
90
|
+
} else {
|
|
91
|
+
this.activate();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
renderActivateButton() {
|
|
96
|
+
this.iframe.style.display = "none";
|
|
97
|
+
|
|
98
|
+
const button = document.createElement("button");
|
|
99
|
+
button.type = "button";
|
|
100
|
+
button.className = "numbl-embed-activate";
|
|
101
|
+
button.textContent = this.getAttribute("label") || "▶ Edit & run in numbl";
|
|
102
|
+
// Inline styles so the button looks reasonable even without external CSS;
|
|
103
|
+
// a page may override via the .numbl-embed-activate class.
|
|
104
|
+
button.style.cssText = [
|
|
105
|
+
"display:inline-flex",
|
|
106
|
+
"align-items:center",
|
|
107
|
+
"gap:0.4em",
|
|
108
|
+
"padding:0.45em 0.9em",
|
|
109
|
+
"font-size:0.85rem",
|
|
110
|
+
"font-family:inherit",
|
|
111
|
+
"color:#fff",
|
|
112
|
+
"background:#2e7d32",
|
|
113
|
+
"border:none",
|
|
114
|
+
"border-radius:4px",
|
|
115
|
+
"cursor:pointer",
|
|
116
|
+
].join(";");
|
|
117
|
+
|
|
118
|
+
button.addEventListener(
|
|
119
|
+
"click",
|
|
120
|
+
() => {
|
|
121
|
+
button.remove();
|
|
122
|
+
this.iframe.style.display = "";
|
|
123
|
+
this.activate();
|
|
124
|
+
},
|
|
125
|
+
{ once: true }
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
this.activateButton = button;
|
|
129
|
+
this.insertBefore(button, this.iframe);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
activate() {
|
|
39
133
|
const defaultNumblUrl = "https://numbl.org";
|
|
40
134
|
const numblUrl = this.attributes["numbl-url"]?.value || defaultNumblUrl;
|
|
41
135
|
const cacheBust = `_cb=${Date.now()}`;
|
|
@@ -49,31 +143,50 @@ class NumblEmbed extends HTMLElement {
|
|
|
49
143
|
|
|
50
144
|
const encodePlain = text => {
|
|
51
145
|
const text2 = text.replace(/</g, "<").replace(/>/g, ">");
|
|
52
|
-
return
|
|
146
|
+
return utf8ToBase64(text2);
|
|
53
147
|
};
|
|
54
148
|
|
|
55
|
-
|
|
149
|
+
// Optional preamble: setup code that runs (hidden) before the visible
|
|
150
|
+
// script. `numbl-preamble` is preferred; `matlab-preamble` is a synonym.
|
|
151
|
+
const preambleElement = this.querySelector(
|
|
152
|
+
"script.numbl-preamble, script.matlab-preamble"
|
|
153
|
+
);
|
|
154
|
+
let preambleParam = preambleElement
|
|
155
|
+
? `&preamble=${encodePlain(preambleElement.textContent.trim())}`
|
|
156
|
+
: "";
|
|
157
|
+
|
|
158
|
+
// Message shown while the preamble runs (defaults to "Preparing..." in the
|
|
159
|
+
// embed page). Override per-embed with the `preparing-label` attribute,
|
|
160
|
+
// e.g. preparing-label="Installing...".
|
|
161
|
+
const preparingLabel = this.getAttribute("preparing-label");
|
|
162
|
+
if (preambleParam && preparingLabel) {
|
|
163
|
+
preambleParam += `&preparing=${utf8ToBase64(preparingLabel)}`;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// `numbl-script` is preferred; `matlab-script` is a synonym.
|
|
167
|
+
const scriptElement = this.querySelector(
|
|
168
|
+
"script.numbl-script, script.matlab-script"
|
|
169
|
+
);
|
|
56
170
|
|
|
57
171
|
let scriptBase64;
|
|
58
172
|
if (scriptElement) {
|
|
59
|
-
|
|
60
|
-
scriptBase64 = encodePlain(matlabScript);
|
|
173
|
+
scriptBase64 = encodePlain(scriptElement.textContent.trim());
|
|
61
174
|
} else if (this.attributes.script) {
|
|
62
175
|
const scriptUrl = this.attributes.script.value;
|
|
63
|
-
this.loadScriptFromUrl(scriptUrl);
|
|
176
|
+
this.loadScriptFromUrl(scriptUrl, preambleParam);
|
|
64
177
|
return;
|
|
65
178
|
} else {
|
|
66
179
|
scriptBase64 = null;
|
|
67
180
|
}
|
|
68
181
|
|
|
69
182
|
if (scriptBase64) {
|
|
70
|
-
this.iframe.src = `${numblUrl}/embed?script=${scriptBase64}&${cacheBust}`;
|
|
183
|
+
this.iframe.src = `${numblUrl}/embed?script=${scriptBase64}${preambleParam}&${cacheBust}`;
|
|
71
184
|
} else {
|
|
72
|
-
this.iframe.src = `${numblUrl}/embed?${cacheBust}`;
|
|
185
|
+
this.iframe.src = `${numblUrl}/embed?${cacheBust}${preambleParam}`;
|
|
73
186
|
}
|
|
74
187
|
}
|
|
75
188
|
|
|
76
|
-
async loadScriptFromUrl(url) {
|
|
189
|
+
async loadScriptFromUrl(url, preambleParam = "") {
|
|
77
190
|
try {
|
|
78
191
|
let absoluteUrl = url;
|
|
79
192
|
if (url.startsWith("./") || url.startsWith("../")) {
|
|
@@ -87,15 +200,15 @@ class NumblEmbed extends HTMLElement {
|
|
|
87
200
|
}
|
|
88
201
|
|
|
89
202
|
const scriptContent = await response.text();
|
|
90
|
-
const scriptBase64 =
|
|
203
|
+
const scriptBase64 = utf8ToBase64(scriptContent);
|
|
91
204
|
|
|
92
205
|
const defaultNumblUrl = "https://numbl.org";
|
|
93
206
|
const numblUrl = this.attributes["numbl-url"]?.value || defaultNumblUrl;
|
|
94
207
|
|
|
95
208
|
const cacheBust = `_cb=${Date.now()}`;
|
|
96
|
-
this.iframe.src = `${numblUrl}/embed?script=${scriptBase64}&${cacheBust}`;
|
|
209
|
+
this.iframe.src = `${numblUrl}/embed?script=${scriptBase64}${preambleParam}&${cacheBust}`;
|
|
97
210
|
} catch (error) {
|
|
98
|
-
console.error("Error loading
|
|
211
|
+
console.error("Error loading script:", error);
|
|
99
212
|
this.iframe.srcdoc = `
|
|
100
213
|
<html>
|
|
101
214
|
<body style="font-family: Arial; padding: 20px;">
|