@oml/markdown 0.15.0 → 0.16.1
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/out/md/md-runtime.js +15 -0
- package/out/md/md-runtime.js.map +1 -1
- package/out/renderers/table-renderer.js +12 -4
- package/out/renderers/table-renderer.js.map +1 -1
- package/out/static/browser-runtime.bundle.js +718 -14
- package/out/static/browser-runtime.bundle.js.map +3 -3
- package/out/static/browser-runtime.js +748 -1
- package/out/static/browser-runtime.js.map +1 -1
- package/out/static/runtime-assets.d.ts +1 -1
- package/out/static/runtime-assets.js +3 -0
- package/out/static/runtime-assets.js.map +1 -1
- package/out/template/engine.js +1 -1
- package/out/template/engine.js.map +1 -1
- package/package.json +2 -2
- package/src/md/md-runtime.ts +17 -0
- package/src/renderers/table-renderer.ts +13 -4
- package/src/static/browser-runtime.ts +803 -1
- package/src/static/markdown-webview.css +81 -1
- package/src/static/runtime-assets.ts +3 -0
- package/src/template/engine.ts +1 -1
|
@@ -4166,8 +4166,8 @@
|
|
|
4166
4166
|
}
|
|
4167
4167
|
return lineValue;
|
|
4168
4168
|
}
|
|
4169
|
-
function garbageCollect(
|
|
4170
|
-
each(
|
|
4169
|
+
function garbageCollect(caches2, length2) {
|
|
4170
|
+
each(caches2, (cache5) => {
|
|
4171
4171
|
const gc = cache5.gc;
|
|
4172
4172
|
const gcLen = gc.length / 2;
|
|
4173
4173
|
let i;
|
|
@@ -9489,7 +9489,7 @@
|
|
|
9489
9489
|
return labelSizes;
|
|
9490
9490
|
}
|
|
9491
9491
|
_computeLabelSizes(ticks, length2, maxTicksLimit) {
|
|
9492
|
-
const { ctx, _longestTextCache:
|
|
9492
|
+
const { ctx, _longestTextCache: caches2 } = this;
|
|
9493
9493
|
const widths = [];
|
|
9494
9494
|
const heights = [];
|
|
9495
9495
|
const increment = Math.floor(length2 / getTicksLimit(length2, maxTicksLimit));
|
|
@@ -9500,7 +9500,7 @@
|
|
|
9500
9500
|
label = ticks[i].label;
|
|
9501
9501
|
tickFont = this._resolveTickFontOptions(i);
|
|
9502
9502
|
ctx.font = fontString = tickFont.string;
|
|
9503
|
-
cache5 =
|
|
9503
|
+
cache5 = caches2[fontString] = caches2[fontString] || {
|
|
9504
9504
|
data: {},
|
|
9505
9505
|
gc: []
|
|
9506
9506
|
};
|
|
@@ -9523,7 +9523,7 @@
|
|
|
9523
9523
|
widestLabelSize = Math.max(width2, widestLabelSize);
|
|
9524
9524
|
highestLabelSize = Math.max(height2, highestLabelSize);
|
|
9525
9525
|
}
|
|
9526
|
-
garbageCollect(
|
|
9526
|
+
garbageCollect(caches2, length2);
|
|
9527
9527
|
const widest = widths.indexOf(widestLabelSize);
|
|
9528
9528
|
const highest = heights.indexOf(highestLabelSize);
|
|
9529
9529
|
const valueAt = (idx) => ({
|
|
@@ -28245,18 +28245,18 @@
|
|
|
28245
28245
|
return [text4, ""];
|
|
28246
28246
|
}
|
|
28247
28247
|
const length2 = text4.length;
|
|
28248
|
-
const
|
|
28248
|
+
const caches2 = {};
|
|
28249
28249
|
let index3 = Math.round(splitWidth / totalWidth * length2 - 1);
|
|
28250
28250
|
if (index3 < 0) {
|
|
28251
28251
|
index3 = 0;
|
|
28252
28252
|
}
|
|
28253
28253
|
while (index3 >= 0 && index3 < length2) {
|
|
28254
28254
|
const frontText = text4.slice(0, index3);
|
|
28255
|
-
const frontWidth =
|
|
28255
|
+
const frontWidth = caches2[frontText] || measureText(frontText, style2).width;
|
|
28256
28256
|
const behindText = text4.slice(0, index3 + 1);
|
|
28257
|
-
const behindWidth =
|
|
28258
|
-
|
|
28259
|
-
|
|
28257
|
+
const behindWidth = caches2[behindText] || measureText(behindText, style2).width;
|
|
28258
|
+
caches2[frontText] = frontWidth;
|
|
28259
|
+
caches2[behindText] = behindWidth;
|
|
28260
28260
|
if (frontWidth > splitWidth) {
|
|
28261
28261
|
index3 -= 1;
|
|
28262
28262
|
} else if (behindWidth <= splitWidth) {
|
|
@@ -73679,6 +73679,13 @@ ${serialized}`;
|
|
|
73679
73679
|
};
|
|
73680
73680
|
|
|
73681
73681
|
// src/renderers/table-renderer.ts
|
|
73682
|
+
function buildTableUiStateKey(blockId) {
|
|
73683
|
+
if (typeof blockId !== "string" || blockId.length === 0) {
|
|
73684
|
+
return void 0;
|
|
73685
|
+
}
|
|
73686
|
+
const pageKey = `${window.location.origin}${window.location.pathname}`;
|
|
73687
|
+
return `${pageKey}::${blockId}`;
|
|
73688
|
+
}
|
|
73682
73689
|
var TableMarkdownBlockRenderer = class extends QueryMarkdownBlockRenderer {
|
|
73683
73690
|
constructor() {
|
|
73684
73691
|
super(...arguments);
|
|
@@ -73760,7 +73767,8 @@ ${serialized}`;
|
|
|
73760
73767
|
const columnContexts = createColumnContexts(visibleColumns, visibleRows);
|
|
73761
73768
|
const treeModel = isTree ? this.createTreeModel(columns, allRowsWithIndex, visibleColumnIndexes, options) : void 0;
|
|
73762
73769
|
const fullyExpandedTreeRows = isTree && treeModel ? this.flattenAllTreeRows(treeModel) : void 0;
|
|
73763
|
-
const
|
|
73770
|
+
const tableUiStateKey = buildTableUiStateKey(blockId);
|
|
73771
|
+
const persistedState = tableUiStateKey ? window.__omlGetPersistedTableUiState?.(tableUiStateKey) : void 0;
|
|
73764
73772
|
const state = {
|
|
73765
73773
|
search: persistedState?.search ?? "",
|
|
73766
73774
|
pageSize: persistedState?.pageSize ?? 50,
|
|
@@ -73773,10 +73781,10 @@ ${serialized}`;
|
|
|
73773
73781
|
expanded: new Set(treeModel?.expandableNodes ?? [])
|
|
73774
73782
|
};
|
|
73775
73783
|
const persistUiState = () => {
|
|
73776
|
-
if (!
|
|
73784
|
+
if (!tableUiStateKey) {
|
|
73777
73785
|
return;
|
|
73778
73786
|
}
|
|
73779
|
-
window.__omlSetPersistedTableUiState?.(
|
|
73787
|
+
window.__omlSetPersistedTableUiState?.(tableUiStateKey, {
|
|
73780
73788
|
search: state.search,
|
|
73781
73789
|
pageSize: state.pageSize,
|
|
73782
73790
|
page: state.page,
|
|
@@ -76014,7 +76022,703 @@ ${serialized}`;
|
|
|
76014
76022
|
}
|
|
76015
76023
|
}
|
|
76016
76024
|
setupDownloadHandler();
|
|
76017
|
-
|
|
76025
|
+
function ensureInitialContentLoaded() {
|
|
76026
|
+
const content9 = document.getElementById("oml-md-content");
|
|
76027
|
+
if (!content9) {
|
|
76028
|
+
return;
|
|
76029
|
+
}
|
|
76030
|
+
if (content9.childNodes.length > 0) {
|
|
76031
|
+
return;
|
|
76032
|
+
}
|
|
76033
|
+
const template = document.getElementById("oml-md-initial-content");
|
|
76034
|
+
if (!(template instanceof HTMLTemplateElement)) {
|
|
76035
|
+
return;
|
|
76036
|
+
}
|
|
76037
|
+
content9.innerHTML = template.innerHTML;
|
|
76038
|
+
}
|
|
76039
|
+
async function bootstrapStaticRender() {
|
|
76040
|
+
void pruneOldRuntimeCaches();
|
|
76041
|
+
const body = document.body;
|
|
76042
|
+
const previousBodyVisibility = body.style.visibility;
|
|
76043
|
+
body.style.visibility = "hidden";
|
|
76044
|
+
ensureInitialContentLoaded();
|
|
76045
|
+
try {
|
|
76046
|
+
await applyExecutionResults();
|
|
76047
|
+
await Promise.all([
|
|
76048
|
+
applyJsBlocks(),
|
|
76049
|
+
applyPyBlocks(),
|
|
76050
|
+
applyRBlocks()
|
|
76051
|
+
]);
|
|
76052
|
+
} finally {
|
|
76053
|
+
document.documentElement.classList.remove("oml-md-booting");
|
|
76054
|
+
document.body.classList.remove("oml-md-booting");
|
|
76055
|
+
body.style.visibility = previousBodyVisibility || "visible";
|
|
76056
|
+
}
|
|
76057
|
+
}
|
|
76058
|
+
function getScriptSparqlCache() {
|
|
76059
|
+
return parseJsonNode("oml-md-script-sparql-cache", {});
|
|
76060
|
+
}
|
|
76061
|
+
var PYTHON_PANEL_CACHE_STORAGE_KEY = "oml-md-python-panel-cache-v1";
|
|
76062
|
+
var R_PANEL_CACHE_STORAGE_KEY = "oml-md-r-panel-cache-v1";
|
|
76063
|
+
var JS_PANEL_CACHE_STORAGE_KEY = "oml-md-js-panel-cache-v1";
|
|
76064
|
+
var MAX_PYTHON_PANEL_CACHE_ENTRIES = 64;
|
|
76065
|
+
var MAX_R_PANEL_CACHE_ENTRIES = 64;
|
|
76066
|
+
var MAX_JS_PANEL_CACHE_ENTRIES = 64;
|
|
76067
|
+
var pythonPanelHtmlCache = readPythonPanelCache();
|
|
76068
|
+
var rPanelHtmlCache = readRPanelCache();
|
|
76069
|
+
var jsPanelHtmlCache = readJsPanelCache();
|
|
76070
|
+
function readPythonPanelCache() {
|
|
76071
|
+
try {
|
|
76072
|
+
const raw2 = window.localStorage.getItem(PYTHON_PANEL_CACHE_STORAGE_KEY);
|
|
76073
|
+
const parsed = raw2 ? JSON.parse(raw2) : {};
|
|
76074
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
76075
|
+
return {};
|
|
76076
|
+
}
|
|
76077
|
+
const cache5 = {};
|
|
76078
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
76079
|
+
if (typeof value === "string") {
|
|
76080
|
+
cache5[key] = value;
|
|
76081
|
+
}
|
|
76082
|
+
}
|
|
76083
|
+
return cache5;
|
|
76084
|
+
} catch {
|
|
76085
|
+
return {};
|
|
76086
|
+
}
|
|
76087
|
+
}
|
|
76088
|
+
function rememberPythonPanelCache(key, html2) {
|
|
76089
|
+
const nextEntries = Object.entries(pythonPanelHtmlCache).filter(([entryKey]) => entryKey !== key);
|
|
76090
|
+
nextEntries.push([key, html2]);
|
|
76091
|
+
while (nextEntries.length > MAX_PYTHON_PANEL_CACHE_ENTRIES) {
|
|
76092
|
+
nextEntries.shift();
|
|
76093
|
+
}
|
|
76094
|
+
pythonPanelHtmlCache = Object.fromEntries(nextEntries);
|
|
76095
|
+
try {
|
|
76096
|
+
window.localStorage.setItem(PYTHON_PANEL_CACHE_STORAGE_KEY, JSON.stringify(pythonPanelHtmlCache));
|
|
76097
|
+
} catch {
|
|
76098
|
+
}
|
|
76099
|
+
}
|
|
76100
|
+
function readRPanelCache() {
|
|
76101
|
+
try {
|
|
76102
|
+
const raw2 = window.localStorage.getItem(R_PANEL_CACHE_STORAGE_KEY);
|
|
76103
|
+
const parsed = raw2 ? JSON.parse(raw2) : {};
|
|
76104
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
76105
|
+
return {};
|
|
76106
|
+
}
|
|
76107
|
+
const cache5 = {};
|
|
76108
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
76109
|
+
if (typeof value === "string") {
|
|
76110
|
+
cache5[key] = value;
|
|
76111
|
+
}
|
|
76112
|
+
}
|
|
76113
|
+
return cache5;
|
|
76114
|
+
} catch {
|
|
76115
|
+
return {};
|
|
76116
|
+
}
|
|
76117
|
+
}
|
|
76118
|
+
function rememberRPanelCache(key, html2) {
|
|
76119
|
+
const nextEntries = Object.entries(rPanelHtmlCache).filter(([entryKey]) => entryKey !== key);
|
|
76120
|
+
nextEntries.push([key, html2]);
|
|
76121
|
+
while (nextEntries.length > MAX_R_PANEL_CACHE_ENTRIES) {
|
|
76122
|
+
nextEntries.shift();
|
|
76123
|
+
}
|
|
76124
|
+
rPanelHtmlCache = Object.fromEntries(nextEntries);
|
|
76125
|
+
try {
|
|
76126
|
+
window.localStorage.setItem(R_PANEL_CACHE_STORAGE_KEY, JSON.stringify(rPanelHtmlCache));
|
|
76127
|
+
} catch {
|
|
76128
|
+
}
|
|
76129
|
+
}
|
|
76130
|
+
function readJsPanelCache() {
|
|
76131
|
+
try {
|
|
76132
|
+
const raw2 = window.localStorage.getItem(JS_PANEL_CACHE_STORAGE_KEY);
|
|
76133
|
+
const parsed = raw2 ? JSON.parse(raw2) : {};
|
|
76134
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
76135
|
+
return {};
|
|
76136
|
+
}
|
|
76137
|
+
const cache5 = {};
|
|
76138
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
76139
|
+
if (typeof value === "string") {
|
|
76140
|
+
cache5[key] = value;
|
|
76141
|
+
}
|
|
76142
|
+
}
|
|
76143
|
+
return cache5;
|
|
76144
|
+
} catch {
|
|
76145
|
+
return {};
|
|
76146
|
+
}
|
|
76147
|
+
}
|
|
76148
|
+
function rememberJsPanelCache(key, html2) {
|
|
76149
|
+
const nextEntries = Object.entries(jsPanelHtmlCache).filter(([entryKey]) => entryKey !== key);
|
|
76150
|
+
nextEntries.push([key, html2]);
|
|
76151
|
+
while (nextEntries.length > MAX_JS_PANEL_CACHE_ENTRIES) {
|
|
76152
|
+
nextEntries.shift();
|
|
76153
|
+
}
|
|
76154
|
+
jsPanelHtmlCache = Object.fromEntries(nextEntries);
|
|
76155
|
+
try {
|
|
76156
|
+
window.localStorage.setItem(JS_PANEL_CACHE_STORAGE_KEY, JSON.stringify(jsPanelHtmlCache));
|
|
76157
|
+
} catch {
|
|
76158
|
+
}
|
|
76159
|
+
}
|
|
76160
|
+
function buildPythonPanelCacheKey(blockId, source, blockCache) {
|
|
76161
|
+
const page = `${window.location.origin}${window.location.pathname}${window.location.search}`;
|
|
76162
|
+
return `python|${page}|${blockId}|${hash32(source)}|${hash32(JSON.stringify(blockCache))}`;
|
|
76163
|
+
}
|
|
76164
|
+
function buildRPanelCacheKey(blockId, source, blockCache) {
|
|
76165
|
+
const page = `${window.location.origin}${window.location.pathname}${window.location.search}`;
|
|
76166
|
+
return `r|${page}|${blockId}|${hash32(source)}|${hash32(JSON.stringify(blockCache))}`;
|
|
76167
|
+
}
|
|
76168
|
+
function buildJsPanelCacheKey(blockId, source, blockCache) {
|
|
76169
|
+
const page = `${window.location.origin}${window.location.pathname}${window.location.search}`;
|
|
76170
|
+
return `js|${page}|${blockId}|${hash32(source)}|${hash32(JSON.stringify(blockCache))}`;
|
|
76171
|
+
}
|
|
76172
|
+
function hash32(input) {
|
|
76173
|
+
let hash = 2166136261;
|
|
76174
|
+
for (let i = 0; i < input.length; i++) {
|
|
76175
|
+
hash ^= input.charCodeAt(i);
|
|
76176
|
+
hash = Math.imul(hash, 16777619);
|
|
76177
|
+
}
|
|
76178
|
+
return (hash >>> 0).toString(16);
|
|
76179
|
+
}
|
|
76180
|
+
function sparqlResultToHtmlTable(result) {
|
|
76181
|
+
if (!result.success || result.rows.length === 0) {
|
|
76182
|
+
const msg = result.error ?? "No results";
|
|
76183
|
+
return result.error ? `<p class="oml-md-js-error">${msg}</p>` : `<p class="oml-md-js-empty">No results</p>`;
|
|
76184
|
+
}
|
|
76185
|
+
const esc = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
76186
|
+
const header = result.columns.map((c) => `<th>${esc(c)}</th>`).join("");
|
|
76187
|
+
const body = result.rows.map(
|
|
76188
|
+
(row) => `<tr>${result.columns.map((c) => `<td>${esc(row[c] ?? "")}</td>`).join("")}</tr>`
|
|
76189
|
+
).join("");
|
|
76190
|
+
return `<div class="oml-md-table-wrapper"><table class="oml-md-table"><thead><tr>${header}</tr></thead><tbody>${body}</tbody></table></div>`;
|
|
76191
|
+
}
|
|
76192
|
+
function makeScriptPanel() {
|
|
76193
|
+
const panel = document.createElement("div");
|
|
76194
|
+
panel.className = "oml-md-js-result";
|
|
76195
|
+
return panel;
|
|
76196
|
+
}
|
|
76197
|
+
function appendResult(panel, result) {
|
|
76198
|
+
if (result.error) {
|
|
76199
|
+
const el = document.createElement("div");
|
|
76200
|
+
el.className = "oml-md-js-error";
|
|
76201
|
+
el.textContent = result.error;
|
|
76202
|
+
panel.appendChild(el);
|
|
76203
|
+
}
|
|
76204
|
+
if (panel.childElementCount === 0) {
|
|
76205
|
+
const el = document.createElement("div");
|
|
76206
|
+
el.className = "oml-md-js-empty";
|
|
76207
|
+
el.textContent = "(no output)";
|
|
76208
|
+
panel.appendChild(el);
|
|
76209
|
+
}
|
|
76210
|
+
}
|
|
76211
|
+
var loadedScripts = /* @__PURE__ */ new Set();
|
|
76212
|
+
async function loadScript(url) {
|
|
76213
|
+
if (loadedScripts.has(url)) {
|
|
76214
|
+
return;
|
|
76215
|
+
}
|
|
76216
|
+
await new Promise((resolve4, reject) => {
|
|
76217
|
+
const script = document.createElement("script");
|
|
76218
|
+
script.src = url;
|
|
76219
|
+
script.onload = () => {
|
|
76220
|
+
loadedScripts.add(url);
|
|
76221
|
+
resolve4();
|
|
76222
|
+
};
|
|
76223
|
+
script.onerror = () => reject(new Error(`Failed to load script: ${url}`));
|
|
76224
|
+
document.head.appendChild(script);
|
|
76225
|
+
});
|
|
76226
|
+
}
|
|
76227
|
+
function isPyodideNoise(text4) {
|
|
76228
|
+
return /^(Loading|Loaded|Unloading) /.test(text4) || text4.includes("already loaded from") || text4.includes("channel");
|
|
76229
|
+
}
|
|
76230
|
+
async function executeJsCode(code2, blockCache, container) {
|
|
76231
|
+
let statusEl = document.createElement("div");
|
|
76232
|
+
statusEl.className = "oml-md-js-text-output";
|
|
76233
|
+
statusEl.textContent = "Running JavaScript block\u2026";
|
|
76234
|
+
container.appendChild(statusEl);
|
|
76235
|
+
const clearStatus = () => {
|
|
76236
|
+
if (statusEl?.parentElement === container) {
|
|
76237
|
+
container.removeChild(statusEl);
|
|
76238
|
+
}
|
|
76239
|
+
statusEl = void 0;
|
|
76240
|
+
};
|
|
76241
|
+
const appendHtml = (html2) => {
|
|
76242
|
+
clearStatus();
|
|
76243
|
+
const el = document.createElement("div");
|
|
76244
|
+
el.className = "oml-md-js-html-output";
|
|
76245
|
+
el.style.color = window.getComputedStyle(document.body).color;
|
|
76246
|
+
el.innerHTML = html2;
|
|
76247
|
+
container.appendChild(el);
|
|
76248
|
+
};
|
|
76249
|
+
const appendText = (text4) => {
|
|
76250
|
+
clearStatus();
|
|
76251
|
+
const pre = document.createElement("pre");
|
|
76252
|
+
pre.className = "oml-md-js-text-output";
|
|
76253
|
+
pre.textContent = text4;
|
|
76254
|
+
container.appendChild(pre);
|
|
76255
|
+
};
|
|
76256
|
+
const display = (content9) => {
|
|
76257
|
+
if (typeof content9 === "string") {
|
|
76258
|
+
appendHtml(content9);
|
|
76259
|
+
} else {
|
|
76260
|
+
appendText(String(content9));
|
|
76261
|
+
}
|
|
76262
|
+
};
|
|
76263
|
+
const query = async (sparql) => {
|
|
76264
|
+
return blockCache[sparql] ?? { success: false, columns: [], rows: [], error: "SPARQL not pre-fetched for this query" };
|
|
76265
|
+
};
|
|
76266
|
+
const table2 = (result) => sparqlResultToHtmlTable(result);
|
|
76267
|
+
const load = async (url) => loadScript(url);
|
|
76268
|
+
const savedLog = console.log;
|
|
76269
|
+
const savedWarn = console.warn;
|
|
76270
|
+
const savedError = console.error;
|
|
76271
|
+
console.log = (...args) => {
|
|
76272
|
+
const text4 = args.map((v2) => typeof v2 === "string" ? v2 : JSON.stringify(v2, null, 2)).join(" ");
|
|
76273
|
+
if (!isPyodideNoise(text4)) {
|
|
76274
|
+
appendText(text4);
|
|
76275
|
+
}
|
|
76276
|
+
};
|
|
76277
|
+
console.warn = console.log;
|
|
76278
|
+
console.error = (...args) => {
|
|
76279
|
+
const text4 = "[error] " + args.map((v2) => typeof v2 === "string" ? v2 : JSON.stringify(v2, null, 2)).join(" ");
|
|
76280
|
+
if (!isPyodideNoise(text4)) {
|
|
76281
|
+
appendText(text4);
|
|
76282
|
+
}
|
|
76283
|
+
};
|
|
76284
|
+
try {
|
|
76285
|
+
const AsyncFunction = Object.getPrototypeOf(async function() {
|
|
76286
|
+
}).constructor;
|
|
76287
|
+
const fn = new AsyncFunction("display", "query", "table", "load", code2);
|
|
76288
|
+
await fn(display, query, table2, load);
|
|
76289
|
+
clearStatus();
|
|
76290
|
+
return {};
|
|
76291
|
+
} catch (error2) {
|
|
76292
|
+
clearStatus();
|
|
76293
|
+
return { error: error2 instanceof Error ? `${error2.name}: ${error2.message}` : String(error2) };
|
|
76294
|
+
} finally {
|
|
76295
|
+
console.log = savedLog;
|
|
76296
|
+
console.warn = savedWarn;
|
|
76297
|
+
console.error = savedError;
|
|
76298
|
+
}
|
|
76299
|
+
}
|
|
76300
|
+
async function applyJsBlocks() {
|
|
76301
|
+
const cache5 = getScriptSparqlCache();
|
|
76302
|
+
const codeNodes = Array.from(document.querySelectorAll("pre > code.language-javascript, pre > code.language-js"));
|
|
76303
|
+
const sourceBlocks = codeNodes.map((code2) => code2.parentElement).filter((pre) => pre instanceof HTMLElement);
|
|
76304
|
+
for (const pre of sourceBlocks) {
|
|
76305
|
+
pre.style.visibility = "hidden";
|
|
76306
|
+
}
|
|
76307
|
+
try {
|
|
76308
|
+
for (const code2 of codeNodes) {
|
|
76309
|
+
const pre = code2.parentElement;
|
|
76310
|
+
const blockId = pre.dataset.omlBlockId ?? "";
|
|
76311
|
+
const blockCache = cache5[blockId] ?? {};
|
|
76312
|
+
const source = code2.textContent ?? "";
|
|
76313
|
+
const cacheKey = buildJsPanelCacheKey(blockId, source, blockCache);
|
|
76314
|
+
const cachedHtml = jsPanelHtmlCache[cacheKey];
|
|
76315
|
+
if (typeof cachedHtml === "string") {
|
|
76316
|
+
const panel2 = makeScriptPanel();
|
|
76317
|
+
panel2.innerHTML = cachedHtml;
|
|
76318
|
+
pre.replaceWith(panel2);
|
|
76319
|
+
continue;
|
|
76320
|
+
}
|
|
76321
|
+
const panel = makeScriptPanel();
|
|
76322
|
+
pre.replaceWith(panel);
|
|
76323
|
+
const result = await executeJsCode(source, blockCache, panel);
|
|
76324
|
+
appendResult(panel, result);
|
|
76325
|
+
if (!result.error) {
|
|
76326
|
+
rememberJsPanelCache(cacheKey, panel.innerHTML);
|
|
76327
|
+
}
|
|
76328
|
+
}
|
|
76329
|
+
} finally {
|
|
76330
|
+
for (const pre of sourceBlocks) {
|
|
76331
|
+
if (pre.isConnected) {
|
|
76332
|
+
pre.style.visibility = "";
|
|
76333
|
+
}
|
|
76334
|
+
}
|
|
76335
|
+
}
|
|
76336
|
+
}
|
|
76337
|
+
var PYODIDE_VERSION = "v0.27.0";
|
|
76338
|
+
var WEBR_VERSION = "v0.4.2";
|
|
76339
|
+
var PYODIDE_CDN_BASE = `https://cdn.jsdelivr.net/pyodide/${PYODIDE_VERSION}/full`;
|
|
76340
|
+
var WEBR_CDN_BASE = `https://webr.r-wasm.org/${WEBR_VERSION}`;
|
|
76341
|
+
var PYODIDE_CACHE_NAME = `oml-pyodide-${PYODIDE_VERSION}`;
|
|
76342
|
+
var WEBR_CACHE_NAME = `oml-webr-${WEBR_VERSION}`;
|
|
76343
|
+
var RUNTIME_CACHE_PREFIXES = ["oml-pyodide-", "oml-webr-"];
|
|
76344
|
+
var runtimeCacheInterceptors = /* @__PURE__ */ new Map();
|
|
76345
|
+
var _originalFetch = globalThis.fetch.bind(globalThis);
|
|
76346
|
+
if ("caches" in globalThis) {
|
|
76347
|
+
globalThis.fetch = async (input, init) => {
|
|
76348
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
76349
|
+
for (const [prefix, cacheName] of runtimeCacheInterceptors) {
|
|
76350
|
+
if (url.startsWith(prefix)) {
|
|
76351
|
+
try {
|
|
76352
|
+
const cache5 = await caches.open(cacheName);
|
|
76353
|
+
const hit = await cache5.match(url);
|
|
76354
|
+
if (hit) {
|
|
76355
|
+
return hit;
|
|
76356
|
+
}
|
|
76357
|
+
const response = await _originalFetch(input, init);
|
|
76358
|
+
if (response.ok) {
|
|
76359
|
+
await cache5.put(url, response.clone());
|
|
76360
|
+
}
|
|
76361
|
+
return response;
|
|
76362
|
+
} catch {
|
|
76363
|
+
break;
|
|
76364
|
+
}
|
|
76365
|
+
}
|
|
76366
|
+
}
|
|
76367
|
+
return _originalFetch(input, init);
|
|
76368
|
+
};
|
|
76369
|
+
}
|
|
76370
|
+
async function pruneOldRuntimeCaches() {
|
|
76371
|
+
if (!("caches" in globalThis)) {
|
|
76372
|
+
return;
|
|
76373
|
+
}
|
|
76374
|
+
const current = /* @__PURE__ */ new Set([PYODIDE_CACHE_NAME, WEBR_CACHE_NAME]);
|
|
76375
|
+
try {
|
|
76376
|
+
const all = await caches.keys();
|
|
76377
|
+
await Promise.all(
|
|
76378
|
+
all.filter((n) => RUNTIME_CACHE_PREFIXES.some((p) => n.startsWith(p)) && !current.has(n)).map((n) => caches.delete(n))
|
|
76379
|
+
);
|
|
76380
|
+
} catch {
|
|
76381
|
+
}
|
|
76382
|
+
}
|
|
76383
|
+
var pyodideInstance = null;
|
|
76384
|
+
var pyodideLoading = null;
|
|
76385
|
+
async function getPyodide() {
|
|
76386
|
+
if (pyodideInstance) {
|
|
76387
|
+
return pyodideInstance;
|
|
76388
|
+
}
|
|
76389
|
+
if (pyodideLoading) {
|
|
76390
|
+
return pyodideLoading;
|
|
76391
|
+
}
|
|
76392
|
+
pyodideLoading = (async () => {
|
|
76393
|
+
runtimeCacheInterceptors.set(PYODIDE_CDN_BASE, PYODIDE_CACHE_NAME);
|
|
76394
|
+
const dynamicImport = new Function("url", "return import(url)");
|
|
76395
|
+
const { loadPyodide } = await dynamicImport(`${PYODIDE_CDN_BASE}/pyodide.mjs`);
|
|
76396
|
+
const py = await loadPyodide({ indexURL: `${PYODIDE_CDN_BASE}/` });
|
|
76397
|
+
await py.loadPackage("micropip");
|
|
76398
|
+
pyodideInstance = py;
|
|
76399
|
+
return py;
|
|
76400
|
+
})();
|
|
76401
|
+
return pyodideLoading;
|
|
76402
|
+
}
|
|
76403
|
+
var PY_BOOTSTRAP = `
|
|
76404
|
+
def display(html):
|
|
76405
|
+
_js_display(str(html))
|
|
76406
|
+
|
|
76407
|
+
async def query(sparql):
|
|
76408
|
+
result = _js_query(sparql)
|
|
76409
|
+
return result.to_py() if hasattr(result, 'to_py') else result
|
|
76410
|
+
|
|
76411
|
+
async def load(package):
|
|
76412
|
+
import micropip as _micropip
|
|
76413
|
+
await _micropip.install(package)
|
|
76414
|
+
|
|
76415
|
+
def table(data):
|
|
76416
|
+
rows, columns = [], []
|
|
76417
|
+
if isinstance(data, dict) and 'rows' in data:
|
|
76418
|
+
rows = data['rows']
|
|
76419
|
+
columns = data.get('columns', list(rows[0].keys()) if rows else [])
|
|
76420
|
+
elif isinstance(data, list) and data and isinstance(data[0], dict):
|
|
76421
|
+
rows, columns = data, list(data[0].keys())
|
|
76422
|
+
else:
|
|
76423
|
+
try:
|
|
76424
|
+
import pandas as _pd
|
|
76425
|
+
if isinstance(data, _pd.DataFrame):
|
|
76426
|
+
columns, rows = list(data.columns), data.to_dict('records')
|
|
76427
|
+
except ImportError:
|
|
76428
|
+
pass
|
|
76429
|
+
if not rows or not columns:
|
|
76430
|
+
display(str(data))
|
|
76431
|
+
return
|
|
76432
|
+
def _e(s):
|
|
76433
|
+
return str(s).replace('&','&').replace('<','<').replace('>','>')
|
|
76434
|
+
hdr = ''.join(f'<th>{_e(c)}</th>' for c in columns)
|
|
76435
|
+
bdy = ''.join(
|
|
76436
|
+
f'<tr>{"".join(f"<td>{_e(r.get(c,"") if isinstance(r,dict) else "")}</td>" for c in columns)}</tr>'
|
|
76437
|
+
for r in rows
|
|
76438
|
+
)
|
|
76439
|
+
display(f'<div class="oml-md-table-wrapper"><table class="oml-md-table"><thead><tr>{hdr}</tr></thead><tbody>{bdy}</tbody></table></div>')
|
|
76440
|
+
`;
|
|
76441
|
+
var pyodideExecQueue = Promise.resolve();
|
|
76442
|
+
async function executePyCode(code2, blockCache, container) {
|
|
76443
|
+
let resolve4;
|
|
76444
|
+
const queued = new Promise((res) => {
|
|
76445
|
+
resolve4 = res;
|
|
76446
|
+
});
|
|
76447
|
+
pyodideExecQueue = pyodideExecQueue.then(() => _executePyCode(code2, blockCache, container).then(resolve4, (e) => resolve4({ error: String(e) })));
|
|
76448
|
+
return queued;
|
|
76449
|
+
}
|
|
76450
|
+
async function _executePyCode(code2, blockCache, container) {
|
|
76451
|
+
if (!container.isConnected) {
|
|
76452
|
+
return {};
|
|
76453
|
+
}
|
|
76454
|
+
let statusEl = document.createElement("div");
|
|
76455
|
+
statusEl.className = "oml-md-js-text-output";
|
|
76456
|
+
statusEl.textContent = "Running Python block\u2026";
|
|
76457
|
+
container.appendChild(statusEl);
|
|
76458
|
+
const clearStatus = () => {
|
|
76459
|
+
if (statusEl?.parentElement === container) {
|
|
76460
|
+
container.removeChild(statusEl);
|
|
76461
|
+
}
|
|
76462
|
+
statusEl = void 0;
|
|
76463
|
+
};
|
|
76464
|
+
const appendHtml = (html2) => {
|
|
76465
|
+
clearStatus();
|
|
76466
|
+
const el = document.createElement("div");
|
|
76467
|
+
el.className = "oml-md-js-html-output";
|
|
76468
|
+
el.style.color = window.getComputedStyle(document.body).color;
|
|
76469
|
+
el.innerHTML = html2;
|
|
76470
|
+
container.appendChild(el);
|
|
76471
|
+
};
|
|
76472
|
+
const appendText = (text4) => {
|
|
76473
|
+
clearStatus();
|
|
76474
|
+
const pre = document.createElement("pre");
|
|
76475
|
+
pre.className = "oml-md-js-text-output";
|
|
76476
|
+
pre.textContent = text4;
|
|
76477
|
+
container.appendChild(pre);
|
|
76478
|
+
};
|
|
76479
|
+
let pyodide;
|
|
76480
|
+
try {
|
|
76481
|
+
pyodide = await getPyodide();
|
|
76482
|
+
} catch (e) {
|
|
76483
|
+
clearStatus();
|
|
76484
|
+
return { error: `Failed to load Pyodide: ${e instanceof Error ? e.message : String(e)}` };
|
|
76485
|
+
}
|
|
76486
|
+
try {
|
|
76487
|
+
await pyodide.runPythonAsync(PY_BOOTSTRAP);
|
|
76488
|
+
} catch (e) {
|
|
76489
|
+
clearStatus();
|
|
76490
|
+
return { error: `Python bootstrap failed: ${e instanceof Error ? e.message : String(e)}` };
|
|
76491
|
+
}
|
|
76492
|
+
pyodide.globals.set("_js_display", appendHtml);
|
|
76493
|
+
pyodide.globals.set("_js_query", (sparql) => blockCache[sparql] ?? { success: false, columns: [], rows: [], error: "SPARQL not pre-fetched" });
|
|
76494
|
+
pyodide.setStdout({ batched: appendText });
|
|
76495
|
+
pyodide.setStderr({ batched: () => {
|
|
76496
|
+
} });
|
|
76497
|
+
try {
|
|
76498
|
+
await pyodide.runPythonAsync(code2);
|
|
76499
|
+
clearStatus();
|
|
76500
|
+
return {};
|
|
76501
|
+
} catch (error2) {
|
|
76502
|
+
clearStatus();
|
|
76503
|
+
return { error: error2 instanceof Error ? `${error2.name}: ${error2.message}` : String(error2) };
|
|
76504
|
+
}
|
|
76505
|
+
}
|
|
76506
|
+
async function applyPyBlocks() {
|
|
76507
|
+
const cache5 = getScriptSparqlCache();
|
|
76508
|
+
for (const code2 of Array.from(document.querySelectorAll("pre > code.language-python"))) {
|
|
76509
|
+
const pre = code2.parentElement;
|
|
76510
|
+
const blockId = pre.dataset.omlBlockId ?? "";
|
|
76511
|
+
const blockCache = cache5[blockId] ?? {};
|
|
76512
|
+
const source = code2.textContent ?? "";
|
|
76513
|
+
const cacheKey = buildPythonPanelCacheKey(blockId, source, blockCache);
|
|
76514
|
+
const cachedHtml = pythonPanelHtmlCache[cacheKey];
|
|
76515
|
+
if (typeof cachedHtml === "string") {
|
|
76516
|
+
const panel2 = makeScriptPanel();
|
|
76517
|
+
panel2.innerHTML = cachedHtml;
|
|
76518
|
+
pre.replaceWith(panel2);
|
|
76519
|
+
continue;
|
|
76520
|
+
}
|
|
76521
|
+
const panel = makeScriptPanel();
|
|
76522
|
+
pre.replaceWith(panel);
|
|
76523
|
+
const result = await executePyCode(source, blockCache, panel);
|
|
76524
|
+
appendResult(panel, result);
|
|
76525
|
+
if (!result.error) {
|
|
76526
|
+
rememberPythonPanelCache(cacheKey, panel.innerHTML);
|
|
76527
|
+
}
|
|
76528
|
+
}
|
|
76529
|
+
}
|
|
76530
|
+
var webRInstance = null;
|
|
76531
|
+
var webRLoading = null;
|
|
76532
|
+
async function getWebR() {
|
|
76533
|
+
if (webRInstance) {
|
|
76534
|
+
return webRInstance;
|
|
76535
|
+
}
|
|
76536
|
+
if (webRLoading) {
|
|
76537
|
+
return webRLoading;
|
|
76538
|
+
}
|
|
76539
|
+
webRLoading = (async () => {
|
|
76540
|
+
runtimeCacheInterceptors.set(WEBR_CDN_BASE, WEBR_CACHE_NAME);
|
|
76541
|
+
const dynamicImport = new Function("url", "return import(url)");
|
|
76542
|
+
const { WebR: WebRClass } = await dynamicImport(`${WEBR_CDN_BASE}/webr.mjs`);
|
|
76543
|
+
const webR = new WebRClass();
|
|
76544
|
+
await webR.init();
|
|
76545
|
+
webRInstance = webR;
|
|
76546
|
+
return webR;
|
|
76547
|
+
})();
|
|
76548
|
+
return webRLoading;
|
|
76549
|
+
}
|
|
76550
|
+
var R_DISPLAY_SENTINEL = "<<OML_DISPLAY>>";
|
|
76551
|
+
var R_DISPLAY_END = "<</OML_DISPLAY>>";
|
|
76552
|
+
var R_BOOTSTRAP = `
|
|
76553
|
+
display <- function(html) {
|
|
76554
|
+
.oml_buf_ <<- c(.oml_buf_, paste0('<<OML_DISPLAY>>', html, '<</OML_DISPLAY>>'))
|
|
76555
|
+
}
|
|
76556
|
+
table <- function(data) {
|
|
76557
|
+
if (is.data.frame(data) || is.matrix(data)) {
|
|
76558
|
+
df <- as.data.frame(data)
|
|
76559
|
+
cols <- colnames(df)
|
|
76560
|
+
hdr <- paste0('<th>', cols, '</th>', collapse='')
|
|
76561
|
+
rows <- apply(df, 1, function(r) {
|
|
76562
|
+
cells <- paste0('<td>', r, '</td>', collapse='')
|
|
76563
|
+
paste0('<tr>', cells, '</tr>')
|
|
76564
|
+
})
|
|
76565
|
+
bdy <- paste(rows, collapse='')
|
|
76566
|
+
display(paste0('<div class="oml-md-table-wrapper"><table class="oml-md-table"><thead><tr>',
|
|
76567
|
+
hdr, '</tr></thead><tbody>', bdy, '</tbody></table></div>'))
|
|
76568
|
+
} else { print(data) }
|
|
76569
|
+
}
|
|
76570
|
+
load <- function(pkg) {
|
|
76571
|
+
if (!requireNamespace(pkg, quietly=TRUE)) { webr::install(pkg) }
|
|
76572
|
+
library(pkg, character.only=TRUE)
|
|
76573
|
+
}
|
|
76574
|
+
`;
|
|
76575
|
+
function buildRDataFrameCode(result, varName) {
|
|
76576
|
+
const rStr = (s) => '"' + s.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "") + '"';
|
|
76577
|
+
if (!result.success) {
|
|
76578
|
+
return `${varName} <- (function() stop(${rStr(result.error ?? "SPARQL query failed")}))()`;
|
|
76579
|
+
}
|
|
76580
|
+
if (result.rows.length === 0) {
|
|
76581
|
+
const colDefs2 = result.columns.map((c) => ` ${rStr(c)} = character(0)`).join(",\n");
|
|
76582
|
+
return `${varName} <- data.frame(${colDefs2 ? "\n" + colDefs2 + ",\n" : ""} stringsAsFactors = FALSE, check.names = FALSE)`;
|
|
76583
|
+
}
|
|
76584
|
+
const colDefs = result.columns.map((col) => {
|
|
76585
|
+
const vals = result.rows.map((row) => rStr(String(row[col] ?? ""))).join(", ");
|
|
76586
|
+
return ` ${rStr(col)} = c(${vals})`;
|
|
76587
|
+
}).join(",\n");
|
|
76588
|
+
return `${varName} <- data.frame(
|
|
76589
|
+
${colDefs},
|
|
76590
|
+
stringsAsFactors = FALSE, check.names = FALSE
|
|
76591
|
+
)`;
|
|
76592
|
+
}
|
|
76593
|
+
function extractRQueryStrings(code2) {
|
|
76594
|
+
const re = /\bquery\s*\(\s*(?:"((?:[^"\\]|\\[\s\S])*)"|'((?:[^'\\]|\\[\s\S])*)')\s*\)/g;
|
|
76595
|
+
const seen = /* @__PURE__ */ new Set();
|
|
76596
|
+
let m;
|
|
76597
|
+
while ((m = re.exec(code2)) !== null) {
|
|
76598
|
+
const raw2 = m[1] ?? m[2];
|
|
76599
|
+
const unesc = raw2.replace(/\\n/g, "\n").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\'/g, "'").replace(/\\\\/g, "\\");
|
|
76600
|
+
seen.add(unesc);
|
|
76601
|
+
}
|
|
76602
|
+
return [...seen];
|
|
76603
|
+
}
|
|
76604
|
+
function rewriteRQueryCalls(code2, queryMap) {
|
|
76605
|
+
const re = /\bquery\s*\(\s*(?:"((?:[^"\\]|\\[\s\S])*)"|'((?:[^'\\]|\\[\s\S])*)')\s*\)/g;
|
|
76606
|
+
return code2.replace(re, (_2, dq, sq) => {
|
|
76607
|
+
const raw2 = dq ?? sq;
|
|
76608
|
+
const sparql = raw2.replace(/\\n/g, "\n").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\'/g, "'").replace(/\\\\/g, "\\");
|
|
76609
|
+
return queryMap.get(sparql) ?? "data.frame()";
|
|
76610
|
+
});
|
|
76611
|
+
}
|
|
76612
|
+
function processROutput(raw2, appendHtml, appendText) {
|
|
76613
|
+
let remaining = raw2;
|
|
76614
|
+
while (remaining.length > 0) {
|
|
76615
|
+
const start = remaining.indexOf(R_DISPLAY_SENTINEL);
|
|
76616
|
+
if (start === -1) {
|
|
76617
|
+
if (remaining.trim()) {
|
|
76618
|
+
appendText(remaining);
|
|
76619
|
+
}
|
|
76620
|
+
break;
|
|
76621
|
+
}
|
|
76622
|
+
if (start > 0) {
|
|
76623
|
+
appendText(remaining.slice(0, start));
|
|
76624
|
+
}
|
|
76625
|
+
const end = remaining.indexOf(R_DISPLAY_END, start + R_DISPLAY_SENTINEL.length);
|
|
76626
|
+
if (end === -1) {
|
|
76627
|
+
appendText(remaining.slice(start));
|
|
76628
|
+
break;
|
|
76629
|
+
}
|
|
76630
|
+
appendHtml(remaining.slice(start + R_DISPLAY_SENTINEL.length, end));
|
|
76631
|
+
remaining = remaining.slice(end + R_DISPLAY_END.length);
|
|
76632
|
+
}
|
|
76633
|
+
}
|
|
76634
|
+
async function executeRCode(code2, blockCache, container) {
|
|
76635
|
+
let statusEl = document.createElement("div");
|
|
76636
|
+
statusEl.className = "oml-md-js-text-output";
|
|
76637
|
+
statusEl.textContent = "Running R block\u2026";
|
|
76638
|
+
container.appendChild(statusEl);
|
|
76639
|
+
const clearStatus = () => {
|
|
76640
|
+
if (statusEl?.parentElement === container) {
|
|
76641
|
+
container.removeChild(statusEl);
|
|
76642
|
+
}
|
|
76643
|
+
statusEl = void 0;
|
|
76644
|
+
};
|
|
76645
|
+
const appendHtml = (html2) => {
|
|
76646
|
+
clearStatus();
|
|
76647
|
+
const el = document.createElement("div");
|
|
76648
|
+
el.className = "oml-md-js-html-output";
|
|
76649
|
+
el.style.color = window.getComputedStyle(document.body).color;
|
|
76650
|
+
el.innerHTML = html2;
|
|
76651
|
+
container.appendChild(el);
|
|
76652
|
+
};
|
|
76653
|
+
const appendText = (text4) => {
|
|
76654
|
+
clearStatus();
|
|
76655
|
+
const pre = document.createElement("pre");
|
|
76656
|
+
pre.className = "oml-md-js-text-output";
|
|
76657
|
+
pre.textContent = text4;
|
|
76658
|
+
container.appendChild(pre);
|
|
76659
|
+
};
|
|
76660
|
+
const queryStrings = extractRQueryStrings(code2);
|
|
76661
|
+
const prefetchResults = queryStrings.map((sparql, i) => {
|
|
76662
|
+
const varName = `.oml_q${i}_`;
|
|
76663
|
+
const result = blockCache[sparql] ?? { success: false, columns: [], rows: [], error: "SPARQL not pre-fetched" };
|
|
76664
|
+
return { sparql, varName, preamble: buildRDataFrameCode(result, varName) };
|
|
76665
|
+
});
|
|
76666
|
+
let webR;
|
|
76667
|
+
try {
|
|
76668
|
+
webR = await getWebR();
|
|
76669
|
+
} catch (e) {
|
|
76670
|
+
clearStatus();
|
|
76671
|
+
return { error: `Failed to load WebR: ${e instanceof Error ? e.message : String(e)}` };
|
|
76672
|
+
}
|
|
76673
|
+
try {
|
|
76674
|
+
await webR.evalRVoid(R_BOOTSTRAP);
|
|
76675
|
+
} catch (e) {
|
|
76676
|
+
clearStatus();
|
|
76677
|
+
return { error: `R bootstrap failed: ${e instanceof Error ? e.message : String(e)}` };
|
|
76678
|
+
}
|
|
76679
|
+
let finalCode = code2;
|
|
76680
|
+
if (prefetchResults.length > 0) {
|
|
76681
|
+
const queryMap = new Map(prefetchResults.map((r) => [r.sparql, r.varName]));
|
|
76682
|
+
finalCode = prefetchResults.map((r) => r.preamble).join("\n") + "\n" + rewriteRQueryCalls(code2, queryMap);
|
|
76683
|
+
}
|
|
76684
|
+
try {
|
|
76685
|
+
await webR.evalRVoid(
|
|
76686
|
+
".oml_buf_ <- character(0)\ntryCatch({\n" + finalCode + '\n}, error = function(e) { .oml_buf_ <<- c(.oml_buf_, paste0("Error: ", conditionMessage(e))) })\n'
|
|
76687
|
+
);
|
|
76688
|
+
const rawOutput = await webR.evalRString('paste(.oml_buf_, collapse="")');
|
|
76689
|
+
processROutput(rawOutput, appendHtml, appendText);
|
|
76690
|
+
clearStatus();
|
|
76691
|
+
return {};
|
|
76692
|
+
} catch (error2) {
|
|
76693
|
+
clearStatus();
|
|
76694
|
+
return { error: error2 instanceof Error ? `${error2.name}: ${error2.message}` : String(error2) };
|
|
76695
|
+
}
|
|
76696
|
+
}
|
|
76697
|
+
async function applyRBlocks() {
|
|
76698
|
+
const cache5 = getScriptSparqlCache();
|
|
76699
|
+
for (const code2 of Array.from(document.querySelectorAll("pre > code.language-r"))) {
|
|
76700
|
+
const pre = code2.parentElement;
|
|
76701
|
+
const blockId = pre.dataset.omlBlockId ?? "";
|
|
76702
|
+
const blockCache = cache5[blockId] ?? {};
|
|
76703
|
+
const source = code2.textContent ?? "";
|
|
76704
|
+
const cacheKey = buildRPanelCacheKey(blockId, source, blockCache);
|
|
76705
|
+
const cachedHtml = rPanelHtmlCache[cacheKey];
|
|
76706
|
+
if (typeof cachedHtml === "string") {
|
|
76707
|
+
const panel2 = makeScriptPanel();
|
|
76708
|
+
panel2.innerHTML = cachedHtml;
|
|
76709
|
+
pre.replaceWith(panel2);
|
|
76710
|
+
continue;
|
|
76711
|
+
}
|
|
76712
|
+
const panel = makeScriptPanel();
|
|
76713
|
+
pre.replaceWith(panel);
|
|
76714
|
+
const result = await executeRCode(source, blockCache, panel);
|
|
76715
|
+
appendResult(panel, result);
|
|
76716
|
+
if (!result.error) {
|
|
76717
|
+
rememberRPanelCache(cacheKey, panel.innerHTML);
|
|
76718
|
+
}
|
|
76719
|
+
}
|
|
76720
|
+
}
|
|
76721
|
+
void bootstrapStaticRender();
|
|
76018
76722
|
})();
|
|
76019
76723
|
/*! Bundled license information:
|
|
76020
76724
|
|