diff --git a/plugins/ms-ai-architect/playground/ms-ai-architect-v3.html b/plugins/ms-ai-architect/playground/ms-ai-architect-v3.html
index bd93c02..02219e1 100644
--- a/plugins/ms-ai-architect/playground/ms-ai-architect-v3.html
+++ b/plugins/ms-ai-architect/playground/ms-ai-architect-v3.html
@@ -2611,17 +2611,613 @@
window.__parseSections = parseSections;
window.__extractField = extractField;
- // ---- Paste-import stub (Step 12 erstatter med faktisk routing) ----
+ // ============================================================
+ // REPORT RENDERERS (Step 12)
+ // ============================================================
+ //
+ // 17 renderers per kanonisk archetype-routing-tabell. Hver renderer
+ // tar parsed data + slot DOM-element, og fyller slot.innerHTML med
+ // markup som matcher design-system BEM-klasser (.pyramide, .matrix,
+ // .findings, .rights-matrix, .capability-matrix, .distribution,
+ // .verdict-block, .pipeline-cockpit, .diff, .aiact-timeline).
+ //
+ // Routing: RENDERERS[command.renderer] for oppslag i handlePasteImport
+ // (under). Verktøy-commands (produces_report=false) får ingen renderer.
+
+ // ---- Felles helpers ----
+
+ function renderEmptyState() {
+ return '
' +
+ '
i
' +
+ '
Ingen data å vise — tom eller ufullstendig parsing.
' +
+ '
';
+ }
+
+ function renderError(errors, slot) {
+ const items = (errors || []).map(function (e) {
+ return '' + escapeHtml(e.section || 'feil') + ': ' + escapeHtml(e.reason || 'Ukjent') + '';
+ }).join('');
+ slot.innerHTML =
+ '' +
+ '
Kunne ikke parse rapporten
' +
+ '
Justér markdown-format og lim inn på nytt.
' +
+ (items ? '
' : '') +
+ '
' +
+ '
';
+ }
+
+ function renderThreatsTable(threats) {
+ if (!threats || !threats.length) return '';
+ const rows = threats.map(function (t) {
+ return '| ' + escapeHtml(t.id || '') + ' | ' + escapeHtml(t.description || '') + ' | ' + escapeHtml(t.severity || '') + ' | ' + escapeHtml(t.mitigation || '') + ' |
';
+ }).join('');
+ return '| ID | Beskrivelse | Severity | Tiltak |
' + rows + '
';
+ }
+
+ function renderFindingsBlock(findings, label) {
+ const items = findings.map(function (f) {
+ return '' +
+ '' +
+ '' + escapeHtml(f.id || '') + '' +
+ '' + escapeHtml(f.recommendation || '') + '' +
+ 'Lokasjon: ' + escapeHtml(f.location || '—') + ' · Severity: ' + escapeHtml(f.severity || '—') + '' +
+ '';
+ }).join('');
+ return '';
+ }
+
+ function renderMatrixHtml(data, cons_max) {
+ cons_max = cons_max || 5;
+ const cells = data.matrix_cells || [];
+ const byPC = {};
+ cells.forEach(function (c) {
+ const k = c.prob + '_' + c.cons;
+ if (!byPC[k]) byPC[k] = [];
+ byPC[k].push(c);
+ });
+ const probSize = 5;
+ let html = 'Konsekvens
';
+ html += '
';
+ for (let cons = cons_max; cons >= 1; cons--) {
+ html += '
' + cons + '
';
+ for (let prob = 1; prob <= probSize; prob++) {
+ const score = prob * cons;
+ const items = byPC[prob + '_' + cons] || [];
+ const bubblesHtml = items.length
+ ? '
' +
+ items.slice(0, 3).map(function (it, i) {
+ return '' + (i + 1) + '';
+ }).join('') +
+ (items.length > 3 ? '+' + (items.length - 3) + '' : '') +
+ '
'
+ : '';
+ html += '
' +
+ '' + score + '' + bubblesHtml +
+ '
';
+ }
+ }
+ html += '
';
+ for (let prob = 1; prob <= probSize; prob++) {
+ html += '
' + prob + '
';
+ }
+ html += '
';
+ html += '
Sannsynlighet
';
+ html += '
';
+ return html;
+ }
+
+ function renderRadarSvg(axes) {
+ if (!axes || !axes.length) return '';
+ const N = axes.length;
+ const cx = 150, cy = 150, R = 100;
+ const points = axes.map(function (a, i) {
+ const angle = (i / N) * 2 * Math.PI - Math.PI / 2;
+ const r = R * (Math.max(0, Math.min(5, a.score)) / 5);
+ return (cx + r * Math.cos(angle)).toFixed(1) + ',' + (cy + r * Math.sin(angle)).toFixed(1);
+ }).join(' ');
+ const labels = axes.map(function (a, i) {
+ const angle = (i / N) * 2 * Math.PI - Math.PI / 2;
+ const x = cx + (R + 25) * Math.cos(angle);
+ const y = cy + (R + 25) * Math.sin(angle);
+ return '' + escapeHtml(a.name) + '';
+ }).join('');
+ const spokes = axes.map(function (a, i) {
+ const angle = (i / N) * 2 * Math.PI - Math.PI / 2;
+ const x = cx + R * Math.cos(angle);
+ const y = cy + R * Math.sin(angle);
+ return '';
+ }).join('');
+ return '' +
+ '
' +
+ '
';
+ }
+
+ // ---- Sub-batch A: Regulatory (6) ----
+
+ function renderAiActPyramid(data, slot) {
+ const norm = (data.risk_level || '').toLowerCase();
+ let activeTier = 'minimal';
+ if (/forbidden|uakseptabel|prohibited|unacceptable/.test(norm)) activeTier = 'forbidden';
+ else if (/høy|high|hoy/.test(norm)) activeTier = 'high';
+ else if (/begrenset|limited/.test(norm)) activeTier = 'limited';
+ else if (/minimal|low/.test(norm)) activeTier = 'minimal';
+
+ const tiers = [
+ { id: 'forbidden', label: 'Uakseptabel risiko (Art. 5)' },
+ { id: 'high', label: 'Høyrisiko (Art. 6 + Annex III)' },
+ { id: 'limited', label: 'Begrenset risiko (Art. 50)' },
+ { id: 'minimal', label: 'Minimal risiko' }
+ ];
+ const tiersHtml = tiers.map(function (t) {
+ const active = (t.id === activeTier);
+ const ariaCurrent = active ? ' aria-current="true"' : '';
+ const marker = active ? ' ← klassifisert' : '';
+ return '' +
+ '
' + escapeHtml(t.label) + '
' +
+ marker +
+ '
';
+ }).join('');
+
+ const obligationsHtml = (data.obligations || []).length
+ ? ''
+ : '';
+ const meta = '';
+ slot.innerHTML = '' + tiersHtml + '
' + meta + obligationsHtml;
+ }
+
+ function renderRequirements(data, slot) {
+ const sevForStatus = function (status) {
+ const s = (status || '').toLowerCase();
+ if (s === 'met') return 'low';
+ if (s === 'partial') return 'medium';
+ if (s === 'missing') return 'critical';
+ return 'info';
+ };
+ const items = (data.items || []).map(function (it, idx) {
+ return '' +
+ '' +
+ 'R-' + String(idx + 1).padStart(2, '0') + '' +
+ '' + escapeHtml(it.requirement) + '' +
+ 'Kilde: ' + escapeHtml(it.source_article || '—') + ' · Status: ' + escapeHtml(it.status || '—') + '' +
+ '';
+ }).join('');
+ slot.innerHTML =
+ '';
+ }
+
+ function renderTransparency(data, slot) {
+ const sectionsHtml = (data.sections || []).map(function (s) {
+ return '' + escapeHtml(s.heading) + '
' + escapeHtml(s.body).replace(/\n/g, '
') + '
';
+ }).join('');
+ slot.innerHTML = '' + sectionsHtml + '';
+ }
+
+ function renderFria(data, slot) {
+ const headerHtml =
+ '' +
+ '
Rettighet
' +
+ '
Impact (0-5)
' +
+ '
Tiltak
' +
+ '
';
+ const rowsHtml = (data.rights || []).map(function (r) {
+ return '' +
+ '
' + escapeHtml(r.name) + '
' +
+ '
' + r.impact + '
' +
+ '
' + escapeHtml(r.mitigation) + '
' +
+ '
';
+ }).join('');
+ slot.innerHTML = '' + headerHtml + rowsHtml + '
';
+ }
+
+ function renderConformity(data, slot) {
+ const stateOf = function (status) {
+ const s = (status || '').toLowerCase();
+ if (s === 'passed' || s === 'met' || s === 'done') return 'passed';
+ if (s === 'active' || s === 'partial' || s === 'in-progress') return 'active';
+ return 'upcoming';
+ };
+ const dlList = data.deadlines || [];
+ let timelineHtml = '';
+ if (dlList.length) {
+ const milestones = dlList.map(function (d, i) {
+ const left = ((i + 1) / (dlList.length + 1)) * 100;
+ return '' +
+ '
' +
+ '
' +
+ '' + escapeHtml(d.date) + '' +
+ '' + escapeHtml(d.milestone) + '' +
+ '
' +
+ '
';
+ }).join('');
+ timelineHtml =
+ '' +
+ '
' +
+ '
' +
+ milestones +
+ '
' +
+ '
';
+ }
+ const sevForStatus = function (status) {
+ const s = (status || '').toLowerCase();
+ if (s === 'met') return 'low';
+ if (s === 'partial') return 'medium';
+ if (s === 'missing') return 'critical';
+ return 'info';
+ };
+ const items = (data.checklist || []).map(function (it, idx) {
+ return '' +
+ '' +
+ 'C-' + String(idx + 1).padStart(2, '0') + '' +
+ '' + escapeHtml(it.requirement) + '' +
+ 'Bevis: ' + escapeHtml(it.evidence || '—') + ' · ' + escapeHtml(it.status || '—') + '' +
+ '';
+ }).join('');
+ const findingsHtml =
+ '';
+ slot.innerHTML = timelineHtml + findingsHtml;
+ }
+
+ function renderDpia(data, slot) {
+ slot.innerHTML = renderMatrixHtml(data, 5) + renderThreatsTable(data.threats);
+ }
+
+ // ---- Sub-batch B: Security (3) ----
+
+ function renderSecurity(data, slot) {
+ const matrixHtml = renderMatrixHtml(data, 6);
+ const radarHtml = renderRadarSvg(data.dimensions || []);
+ const findingsHtml = renderFindingsBlock(data.findings || [], 'Sikkerhetsfunn');
+ slot.innerHTML = matrixHtml + radarHtml + findingsHtml;
+ }
+
+ function renderRos(data, slot) {
+ const matrixHtml = renderMatrixHtml(data, 5);
+ const radarHtml = renderRadarSvg(data.radar_axes || []);
+ slot.innerHTML = matrixHtml + radarHtml + renderThreatsTable(data.threats);
+ }
+
+ function renderReview(data, slot) {
+ slot.innerHTML = renderFindingsBlock(data.findings || [], 'Funn');
+ }
+
+ // ---- Sub-batch C: Economy (2) ----
+
+ function renderCost(data, slot) {
+ const p10 = data.p10 ? data.p10.monthly : 0;
+ const p50 = data.p50 ? data.p50.monthly : 0;
+ const p90 = data.p90 ? data.p90.monthly : 0;
+ const max = Math.max(p10, p50, p90, 1);
+ const distRows = [
+ { label: 'P10 (lavt)', value: p10 },
+ { label: 'P50 (median)', value: p50 },
+ { label: 'P90 (høyt)', value: p90 }
+ ].map(function (r) {
+ const w = (r.value / max) * 100;
+ return '' +
+ '
' + escapeHtml(r.label) + '
' +
+ '
' +
+ '
' +
+ '
' +
+ '' + r.value.toLocaleString('nb-NO') + ' NOK' +
+ '
' +
+ '
' +
+ '
';
+ }).join('');
+ const distHtml =
+ '' + distRows +
+ '
' +
+ '0' + Math.floor(max / 2).toLocaleString('nb-NO') + '' + max.toLocaleString('nb-NO') + ' NOK/mnd' +
+ '
' +
+ '
';
+ const breakdownRows = (data.monthly_breakdown || []).map(function (m) {
+ return '| ' + escapeHtml(m.component) + ' | ' + m.cost.toLocaleString('nb-NO') + ' NOK |
';
+ }).join('');
+ const breakdownHtml = breakdownRows
+ ? '| Komponent | NOK/mnd |
' + breakdownRows + '
'
+ : '';
+ const tcoHeaders = data.tco_headers || [];
+ const tcoHeader = tcoHeaders.map(function (h) { return '' + escapeHtml(h) + ' | '; }).join('');
+ const tcoRows = (data.tco_table || []).map(function (r) {
+ const cells = tcoHeaders.map(function (h) { return '' + escapeHtml(r[h] || '') + ' | '; }).join('');
+ return '' + cells + '
';
+ }).join('');
+ const tcoHtml = tcoRows
+ ? '' + tcoHeader + '
' + tcoRows + '
'
+ : '';
+ slot.innerHTML = distHtml + breakdownHtml + tcoHtml;
+ }
+
+ function renderLicense(data, slot) {
+ const licenses = data.licenses || [];
+ if (!licenses.length) { slot.innerHTML = renderEmptyState(); return; }
+ const headHtml =
+ '' +
+ '
Kapabilitet
' +
+ licenses.map(function (l) {
+ return '
' + escapeHtml(l.name) + '
';
+ }).join('') +
+ '
';
+ const capabilityNames = (licenses[0].capabilities || []).map(function (c) { return c.name; });
+ const rowsHtml = capabilityNames.map(function (capName, capIdx) {
+ const cells = licenses.map(function (l) {
+ const cap = l.capabilities[capIdx];
+ const status = (cap && cap.status) || 'missing';
+ return '';
+ }).join('');
+ return '' +
+ '
' + escapeHtml(capName) + '
' +
+ cells +
+ '
';
+ }).join('');
+ slot.innerHTML = '' +
+ headHtml + rowsHtml + '
';
+ }
+
+ // ---- Sub-batch D: Documentation (6) ----
+
+ function renderMigrate(data, slot) {
+ const phases = data.phases || [];
+ if (!phases.length) { slot.innerHTML = renderEmptyState(); return; }
+ const milestones = phases.map(function (p, i) {
+ const left = ((i + 1) / (phases.length + 1)) * 100;
+ return '' +
+ '
' +
+ '
' +
+ '' + (p.duration_weeks ? p.duration_weeks + ' uker' : '') + '' +
+ '' + escapeHtml(p.name) + '' +
+ '
' +
+ '
';
+ }).join('');
+ const timelineHtml =
+ '' +
+ '
' +
+ '
' +
+ milestones +
+ '
' +
+ '
';
+ const detailsHtml = phases.map(function (p) {
+ const ms = (p.milestones || []).map(function (m) { return '' + escapeHtml(m) + ''; }).join('');
+ const sc = (p.success_criteria || []).map(function (s) { return '' + escapeHtml(s) + ''; }).join('');
+ return '' +
+ '' + escapeHtml(p.name) + ' (' + (p.duration_weeks || '?') + ' uker)
' +
+ (ms ? 'Milepæler
' : '') +
+ (sc ? 'Suksesskriterier
' : '') +
+ '';
+ }).join('');
+ const risksRows = (data.risks || []).map(function (r) {
+ return '| ' + escapeHtml(r.risk || '') + ' | ' + escapeHtml(r.probability || '') + ' | ' + escapeHtml(r.consequence || '') + ' | ' + escapeHtml(r.mitigation || '') + ' |
';
+ }).join('');
+ const risksHtml = risksRows
+ ? '| Risiko | Sannsynlighet | Konsekvens | Tiltak |
' + risksRows + '
'
+ : '';
+ slot.innerHTML = timelineHtml + detailsHtml + risksHtml;
+ }
+
+ function renderAdr(data, slot) {
+ const meta =
+ '' +
+ (data.status ? '- Status
- ' + escapeHtml(data.status) + '
' : '') +
+ (data.date ? '- Date
- ' + escapeHtml(data.date) + '
' : '') +
+ (data.deciders ? '- Deciders
- ' + escapeHtml(data.deciders) + '
' : '') +
+ '
';
+ const sectionsHtml = (data.sections || []).map(function (s) {
+ return '' + escapeHtml(s.heading) + '
' + escapeHtml(s.body).replace(/\n/g, '
') + '
';
+ }).join('');
+ slot.innerHTML =
+ '' +
+ '' + escapeHtml(data.title || 'ADR') + '
' +
+ meta +
+ sectionsHtml +
+ '';
+ }
+
+ function renderSummary(data, slot) {
+ const verdictMap = {
+ block: { variant: 'block', label: 'BLOCK' },
+ warning: { variant: 'warning', label: 'WARNING' },
+ allow: { variant: 'allow', label: 'ALLOW' }
+ };
+ const v = verdictMap[(data.verdict || '').toLowerCase()] || { variant: 'warning', label: (data.verdict || '?').toUpperCase() };
+ const score = v.variant === 'block' ? 92 : v.variant === 'warning' ? 55 : 22;
+ const verdictHtml =
+ '' +
+ '
' +
+ '
' + escapeHtml(v.label) + '
' +
+ '
' + escapeHtml(data.sub || 'AI-vurdering') + '
' +
+ '
' +
+ '
' +
+ '
' +
+ '' + score + '' +
+ 'heuristisk score (0-100)' +
+ '
' +
+ '
' +
+ '
' +
+ 'AllowNoticeWarningBlockCritical' +
+ '
' +
+ '
' +
+ '
';
+ const rationaleHtml = data.rationale
+ ? 'Rationale
' + escapeHtml(data.rationale).replace(/\n/g, '
') + '
'
+ : '';
+ let metricsHtml = '';
+ if ((data.key_metrics || []).length) {
+ const headers = data.metrics_headers || Object.keys(data.key_metrics[0] || {});
+ const headerRow = headers.map(function (h) { return '' + escapeHtml(h) + ' | '; }).join('');
+ const rows = data.key_metrics.map(function (m) {
+ const cells = headers.map(function (h) { return '' + escapeHtml(m[h] || '') + ' | '; }).join('');
+ return '' + cells + '
';
+ }).join('');
+ metricsHtml = 'Key Metrics
' + headerRow + '
' + rows + '
';
+ }
+ const nextHtml = (data.next_steps || []).length
+ ? 'Next Steps
' + data.next_steps.map(function (s) { return '- ' + escapeHtml(s) + '
'; }).join('') + '
'
+ : '';
+ slot.innerHTML = verdictHtml + rationaleHtml + metricsHtml + nextHtml;
+ }
+
+ function renderPoc(data, slot) {
+ const phases = data.phases || [];
+ if (!phases.length) { slot.innerHTML = renderEmptyState(); return; }
+ const stagesHtml = phases.map(function (p, i) {
+ const num = String(i + 1).padStart(2, '0');
+ const isCurrent = (i === 0);
+ return '' +
+ '
' + num + '
' +
+ '
' + escapeHtml(p.name) + '
' +
+ '
' + (p.duration_weeks || '?') + ' uker
' +
+ '
';
+ }).join('');
+ const cockpitHtml = '' + stagesHtml + '
';
+ const detailsHtml = phases.map(function (p) {
+ const ms = (p.milestones || []).map(function (m) { return '' + escapeHtml(m) + ''; }).join('');
+ const sc = (p.success_criteria || []).map(function (s) { return '' + escapeHtml(s) + ''; }).join('');
+ return '' +
+ '' + escapeHtml(p.name) + ' (' + (p.duration_weeks || '?') + ' uker)
' +
+ (ms ? 'Milepæler
' : '') +
+ (sc ? 'Suksesskriterier
' : '') +
+ '';
+ }).join('');
+ const risksRows = (data.risks || []).map(function (r) {
+ return '| ' + escapeHtml(r.risk || '') + ' | ' + escapeHtml(r.probability || '') + ' | ' + escapeHtml(r.consequence || '') + ' | ' + escapeHtml(r.mitigation || '') + ' |
';
+ }).join('');
+ const risksHtml = risksRows
+ ? '| Risiko | Sannsynlighet | Konsekvens | Tiltak |
' + risksRows + '
'
+ : '';
+ slot.innerHTML = cockpitHtml + detailsHtml + risksHtml;
+ }
+
+ function renderUtredning(data, slot) {
+ const tocHtml = (data.sections || []).map(function (s, i) {
+ return '' + escapeHtml(s.heading) + '';
+ }).join('');
+ const sectionsHtml = (data.sections || []).map(function (s, i) {
+ return '' + escapeHtml(s.heading) + '
' + escapeHtml(s.body).replace(/\n/g, '
') + '
';
+ }).join('');
+ slot.innerHTML =
+ '' +
+ '
' +
+ '
' +
+ '' + escapeHtml(data.title || 'Utredning') + '
' +
+ sectionsHtml +
+ '' +
+ '
';
+ }
+
+ function renderCompare(data, slot) {
+ const subjects = (data.subjects && data.subjects.length === 2) ? data.subjects : ['Subjekt 1', 'Subjekt 2'];
+ const firstWord = function (s) { return (s || '').toLowerCase().split(/\s+/)[0] || ''; };
+ const fw1 = firstWord(subjects[0]);
+ const fw2 = firstWord(subjects[1]);
+ let count1 = 0, count2 = 0, lik = 0;
+ (data.rows || []).forEach(function (r) {
+ const w = (r.winner || '').toLowerCase();
+ if (!w || /lik|begge|—|-/.test(w)) lik++;
+ else if (fw1 && w.indexOf(fw1) >= 0) count1++;
+ else if (fw2 && w.indexOf(fw2) >= 0) count2++;
+ else lik++;
+ });
+ const summaryHtml =
+ '' +
+ '
' + count1 + ' ' + escapeHtml(subjects[0]) + '
' +
+ '
' + count2 + ' ' + escapeHtml(subjects[1]) + '
' +
+ '
' + lik + ' Lik
' +
+ '
';
+ const headerHtml =
+ '' +
+ '
' + escapeHtml(subjects[0]) + '
' +
+ '
' + escapeHtml(subjects[1]) + '
' +
+ '
';
+ const rowsHtml = (data.rows || []).map(function (r) {
+ const w = (r.winner || '').toLowerCase();
+ let cls1 = 'diff__cell--unchanged', cls2 = 'diff__cell--unchanged';
+ if (fw1 && w.indexOf(fw1) >= 0) cls1 = 'diff__cell--added';
+ if (fw2 && w.indexOf(fw2) >= 0) cls2 = 'diff__cell--added';
+ return '' +
+ '
' + escapeHtml(r.aspect) + ': ' + escapeHtml(r.value1) + '
' +
+ '
' + escapeHtml(r.aspect) + ': ' + escapeHtml(r.value2) + '
' +
+ '
';
+ }).join('');
+ slot.innerHTML = '' + summaryHtml + headerHtml + rowsHtml + '
';
+ }
+
+ // ---- RENDERERS routing-objekt (17 commands) ----
+
+ const RENDERERS = {
+ renderAiActPyramid: renderAiActPyramid,
+ renderRequirements: renderRequirements,
+ renderTransparency: renderTransparency,
+ renderFria: renderFria,
+ renderConformity: renderConformity,
+ renderDpia: renderDpia,
+ renderSecurity: renderSecurity,
+ renderRos: renderRos,
+ renderReview: renderReview,
+ renderCost: renderCost,
+ renderLicense: renderLicense,
+ renderMigrate: renderMigrate,
+ renderAdr: renderAdr,
+ renderSummary: renderSummary,
+ renderPoc: renderPoc,
+ renderUtredning: renderUtredning,
+ renderCompare: renderCompare
+ };
+ window.__RENDERERS = RENDERERS;
+
+ // ---- Paste-import: parser + renderer routing (replaces stub) ----
function handlePasteImport(commandId, markdown) {
- // Stub: logger til konsoll for å verifisere DOM-kontrakten. Step 12
- // henter PARSERS[CATALOG[id].report_archetype] + RENDERERS[id], parser
- // markdown og injiserer i [data-report-slot=""].
- console.log('parse-pending:', commandId, (markdown || '').slice(0, 80));
+ const cmd = (CATALOG.commands || []).find(function (c) { return c.id === commandId; });
const slot = document.querySelector('[data-report-slot="' + commandId + '"]');
- if (slot) {
- slot.innerHTML = '⏳
Markdown mottatt (' + (markdown || '').length + ' tegn). Parser+renderer kommer i Step 12.
';
+ if (!cmd || !cmd.produces_report) {
+ if (slot) slot.innerHTML = renderEmptyState();
+ return;
}
+ if (!slot) return;
+ const parser = PARSERS[cmd.report_archetype];
+ const renderer = RENDERERS[cmd.renderer];
+ if (!parser || !renderer) {
+ slot.innerHTML = 'Routing-feil
Mangler parser eller renderer for ' + escapeHtml(cmd.id) + '.
';
+ return;
+ }
+ const result = parser(markdown);
+ slot.innerHTML = '';
+ if (result.ok) renderer(result.data, slot);
+ else renderError(result.errors, slot);
}
window.__handlePasteImport = handlePasteImport;