@oml/markdown 0.14.17 → 0.16.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.
Files changed (38) hide show
  1. package/out/md/md-frontmatter.d.ts +1 -1
  2. package/out/md/md-frontmatter.js +6 -11
  3. package/out/md/md-frontmatter.js.map +1 -1
  4. package/out/md/md-runtime.js +26 -7
  5. package/out/md/md-runtime.js.map +1 -1
  6. package/out/md/md-types.d.ts +2 -2
  7. package/out/renderers/table-renderer.js +12 -4
  8. package/out/renderers/table-renderer.js.map +1 -1
  9. package/out/static/browser-runtime.bundle.js +718 -14
  10. package/out/static/browser-runtime.bundle.js.map +3 -3
  11. package/out/static/browser-runtime.js +748 -1
  12. package/out/static/browser-runtime.js.map +1 -1
  13. package/out/static/runtime-assets.d.ts +1 -1
  14. package/out/static/runtime-assets.js +3 -0
  15. package/out/static/runtime-assets.js.map +1 -1
  16. package/out/template/binder.js +156 -32
  17. package/out/template/binder.js.map +1 -1
  18. package/out/template/compose.d.ts +1 -2
  19. package/out/template/compose.js +7 -41
  20. package/out/template/compose.js.map +1 -1
  21. package/out/template/definition.js +0 -11
  22. package/out/template/definition.js.map +1 -1
  23. package/out/template/engine.js +1 -1
  24. package/out/template/engine.js.map +1 -1
  25. package/out/template/types.d.ts +0 -2
  26. package/package.json +2 -2
  27. package/src/md/md-frontmatter.ts +6 -11
  28. package/src/md/md-runtime.ts +29 -7
  29. package/src/md/md-types.ts +2 -2
  30. package/src/renderers/table-renderer.ts +13 -4
  31. package/src/static/browser-runtime.ts +803 -1
  32. package/src/static/markdown-webview.css +88 -1
  33. package/src/static/runtime-assets.ts +3 -0
  34. package/src/template/binder.ts +165 -35
  35. package/src/template/compose.ts +8 -45
  36. package/src/template/definition.ts +0 -12
  37. package/src/template/engine.ts +1 -1
  38. package/src/template/types.ts +0 -9
@@ -4166,8 +4166,8 @@
4166
4166
  }
4167
4167
  return lineValue;
4168
4168
  }
4169
- function garbageCollect(caches, length2) {
4170
- each(caches, (cache5) => {
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: caches } = this;
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 = caches[fontString] = caches[fontString] || {
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(caches, length2);
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 caches = {};
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 = caches[frontText] || measureText(frontText, style2).width;
28255
+ const frontWidth = caches2[frontText] || measureText(frontText, style2).width;
28256
28256
  const behindText = text4.slice(0, index3 + 1);
28257
- const behindWidth = caches[behindText] || measureText(behindText, style2).width;
28258
- caches[frontText] = frontWidth;
28259
- caches[behindText] = behindWidth;
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 persistedState = blockId ? window.__omlGetPersistedTableUiState?.(blockId) : void 0;
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 (!blockId) {
73784
+ if (!tableUiStateKey) {
73777
73785
  return;
73778
73786
  }
73779
- window.__omlSetPersistedTableUiState?.(blockId, {
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
- void applyExecutionResults();
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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
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('&','&amp;').replace('<','&lt;').replace('>','&gt;')
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