hyperbook 0.85.0 → 0.86.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/dist/assets/directive-embed/client.js +5 -5
- package/dist/assets/directive-embed/style.css +14 -18
- package/dist/assets/directive-struktolab/client.js +54 -0
- package/dist/assets/directive-struktolab/struktolab-editor.umd.js +190 -0
- package/dist/assets/directive-struktolab/struktolab-renderer.umd.js +47 -0
- package/dist/assets/directive-struktolab/style.css +0 -0
- package/dist/assets/directive-youtube/client.js +5 -5
- package/dist/assets/directive-youtube/style.css +15 -16
- package/dist/assets/store.js +2 -1
- package/dist/index.js +86 -14
- package/package.json +3 -3
|
@@ -26,7 +26,7 @@ hyperbook.embed.consent = (function () {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
function loadContent(wrapper) {
|
|
29
|
-
var banner = wrapper.querySelector(".directive-embed
|
|
29
|
+
var banner = wrapper.querySelector(".directive-embed .consent-banner");
|
|
30
30
|
if (banner) {
|
|
31
31
|
banner.remove();
|
|
32
32
|
}
|
|
@@ -55,9 +55,9 @@ hyperbook.embed.consent = (function () {
|
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
var btn = wrapper.querySelector(".directive-embed
|
|
58
|
+
var btn = wrapper.querySelector(".directive-embed .consent-accept-btn");
|
|
59
59
|
var checkbox = wrapper.querySelector(
|
|
60
|
-
".directive-embed
|
|
60
|
+
".directive-embed .consent-always-checkbox"
|
|
61
61
|
);
|
|
62
62
|
if (btn) {
|
|
63
63
|
btn.addEventListener("click", async function () {
|
|
@@ -67,7 +67,7 @@ hyperbook.embed.consent = (function () {
|
|
|
67
67
|
loadContent(wrapper);
|
|
68
68
|
if (checkbox && checkbox.checked) {
|
|
69
69
|
document
|
|
70
|
-
.querySelectorAll(".directive-embed
|
|
70
|
+
.querySelectorAll(".directive-embed .consent")
|
|
71
71
|
.forEach(function (el) {
|
|
72
72
|
var elSrc = el.getAttribute("data-consent-src");
|
|
73
73
|
if (getDomain(elSrc) === domain) {
|
|
@@ -81,7 +81,7 @@ hyperbook.embed.consent = (function () {
|
|
|
81
81
|
|
|
82
82
|
function init(root) {
|
|
83
83
|
var wrappers = root.querySelectorAll
|
|
84
|
-
? root.querySelectorAll(".directive-embed
|
|
84
|
+
? root.querySelectorAll(".directive-embed .consent")
|
|
85
85
|
: [];
|
|
86
86
|
wrappers.forEach(function (w) {
|
|
87
87
|
initWrapper(w);
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
width: 100%;
|
|
3
3
|
position: relative;
|
|
4
4
|
overflow: hidden;
|
|
5
|
-
background-color: white;
|
|
6
5
|
border-radius: 8px;
|
|
7
6
|
border-style: solid;
|
|
8
7
|
border-width: 2px;
|
|
@@ -22,46 +21,44 @@
|
|
|
22
21
|
position: absolute;
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
.directive-embed
|
|
24
|
+
.directive-embed .consent {
|
|
26
25
|
position: absolute;
|
|
27
26
|
top: 0;
|
|
28
27
|
left: 0;
|
|
29
28
|
width: 100%;
|
|
30
29
|
height: 100%;
|
|
30
|
+
padding: 24px;
|
|
31
|
+
overflow: auto;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
.directive-embed
|
|
34
|
+
.directive-embed .consent iframe[data-consent-src] {
|
|
34
35
|
display: none;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
.directive-embed
|
|
38
|
+
.directive-embed .consent-banner {
|
|
38
39
|
display: flex;
|
|
39
40
|
flex-direction: column;
|
|
40
41
|
align-items: center;
|
|
41
42
|
justify-content: center;
|
|
42
43
|
gap: 12px;
|
|
43
|
-
padding: 24px;
|
|
44
|
-
background-color: var(--color-background-tinted, #f5f5f5);
|
|
45
44
|
border-radius: 8px;
|
|
46
45
|
text-align: center;
|
|
47
|
-
height: 100%;
|
|
48
46
|
box-sizing: border-box;
|
|
49
47
|
}
|
|
50
48
|
|
|
51
|
-
.directive-embed
|
|
49
|
+
.directive-embed .consent-banner-text {
|
|
52
50
|
font-size: 0.95em;
|
|
53
51
|
line-height: 1.5;
|
|
54
52
|
color: var(--color-text, #333);
|
|
55
53
|
max-width: 600px;
|
|
56
54
|
}
|
|
57
55
|
|
|
58
|
-
.directive-embed
|
|
56
|
+
.directive-embed .consent-banner-url {
|
|
59
57
|
font-size: 0.85em;
|
|
60
|
-
color: var(--color-text-muted, #666);
|
|
61
58
|
word-break: break-all;
|
|
62
59
|
}
|
|
63
60
|
|
|
64
|
-
.directive-embed
|
|
61
|
+
.directive-embed .consent-always-label {
|
|
65
62
|
display: flex;
|
|
66
63
|
align-items: center;
|
|
67
64
|
gap: 6px;
|
|
@@ -70,23 +67,22 @@
|
|
|
70
67
|
cursor: pointer;
|
|
71
68
|
}
|
|
72
69
|
|
|
73
|
-
.directive-embed
|
|
70
|
+
.directive-embed .consent-always-checkbox {
|
|
74
71
|
cursor: pointer;
|
|
75
|
-
margin: 0!important;
|
|
76
72
|
vertical-align: middle;
|
|
77
73
|
}
|
|
78
74
|
|
|
79
|
-
.directive-embed
|
|
75
|
+
.directive-embed .consent-accept-btn {
|
|
80
76
|
padding: 8px 24px;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
border:
|
|
77
|
+
color: var(--color-brand);
|
|
78
|
+
background: none;
|
|
79
|
+
border: 1px solid var(--color-brand);
|
|
84
80
|
border-radius: 4px;
|
|
85
81
|
cursor: pointer;
|
|
86
82
|
font-size: 0.95em;
|
|
87
83
|
}
|
|
88
84
|
|
|
89
|
-
.directive-embed
|
|
85
|
+
.directive-embed .consent-accept-btn:hover {
|
|
90
86
|
opacity: 0.9;
|
|
91
87
|
}
|
|
92
88
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/// <reference path="../hyperbook.types.js" />
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @type {HyperbookStruktolab}
|
|
5
|
+
* @memberof hyperbook
|
|
6
|
+
* @see hyperbook.store
|
|
7
|
+
*/
|
|
8
|
+
hyperbook.struktolab = (function () {
|
|
9
|
+
const init = (root) => {
|
|
10
|
+
let allStruktolabEditors = root.querySelectorAll("struktolab-editor");
|
|
11
|
+
|
|
12
|
+
allStruktolabEditors.forEach((editor) => {
|
|
13
|
+
const editorId = editor.getAttribute("data-id");
|
|
14
|
+
|
|
15
|
+
// Load saved content for this editor
|
|
16
|
+
hyperbook.store.struktolab.get(editorId).then((result) => {
|
|
17
|
+
if (result) {
|
|
18
|
+
editor.loadJSON(JSON.parse(result.tree));
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Listen for changes in the editor
|
|
23
|
+
editor.addEventListener("change", (e) => {
|
|
24
|
+
hyperbook.store.struktolab.put({
|
|
25
|
+
id: editorId,
|
|
26
|
+
tree: JSON.stringify(e.detail.tree),
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Initialize existing elements on document load
|
|
33
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
34
|
+
init(document);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Observe for new tabs added to the DOM
|
|
38
|
+
const observer = new MutationObserver((mutations) => {
|
|
39
|
+
mutations.forEach((mutation) => {
|
|
40
|
+
mutation.addedNodes.forEach((node) => {
|
|
41
|
+
if (node.nodeType === 1) {
|
|
42
|
+
// Element node
|
|
43
|
+
init(node);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
init,
|
|
53
|
+
};
|
|
54
|
+
})();
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
(function(Y,it){typeof exports=="object"&&typeof module<"u"?it(exports):typeof define=="function"&&define.amd?define(["exports"],it):(Y=typeof globalThis<"u"?globalThis:Y||self,it(Y.StruktolabEditor={}))})(this,(function(Y){"use strict";const it="http://www.w3.org/2000/svg",Ot={color:o=>({TaskNode:"rgb(253, 237, 206)",InputNode:"rgb(253, 237, 206)",OutputNode:"rgb(253, 237, 206)",HeadLoopNode:"rgb(220, 239, 231)",CountLoopNode:"rgb(220, 239, 231)",FootLoopNode:"rgb(220, 239, 231)",BranchNode:"rgb(250, 218, 209)",CaseNode:"rgb(250, 218, 209)",InsertCase:"rgb(250, 218, 209)",TryCatchNode:"rgb(250, 218, 209)",FunctionNode:"rgb(255, 255, 255)"})[o],bw:o=>({TaskNode:"rgb(255, 255, 255)",InputNode:"rgb(255, 255, 255)",OutputNode:"rgb(255, 255, 255)",HeadLoopNode:"rgb(255, 255, 255)",CountLoopNode:"rgb(255, 255, 255)",FootLoopNode:"rgb(255, 255, 255)",BranchNode:"rgb(255, 255, 255)",CaseNode:"rgb(255, 255, 255)",InsertCase:"rgb(255, 255, 255)",TryCatchNode:"rgb(255, 255, 255)",FunctionNode:"rgb(255, 255, 255)"})[o]||"rgb(255, 255, 255)",greyscale:o=>({TaskNode:"rgb(250, 250, 250)",InputNode:"rgb(250, 250, 250)",OutputNode:"rgb(250, 250, 250)",HeadLoopNode:"rgb(245, 245, 245)",CountLoopNode:"rgb(245, 245, 245)",FootLoopNode:"rgb(245, 245, 245)",BranchNode:"rgb(240, 240, 240)",CaseNode:"rgb(240, 240, 240)",InsertCase:"rgb(240, 240, 240)",TryCatchNode:"rgb(240, 240, 240)",FunctionNode:"rgb(255, 255, 255)"})[o]};let Mt="color";function et(o){return Ot[Mt](o)}const yt=40,w=20,X=8,lt=6,se="#333",Wt=1.5;let wt=0;function ft(o){wt=o}let xt=null;function re(o){xt||(xt=document.createElement("canvas"));const t=xt.getContext("2d");return t.font=`${o}px sans-serif`,t}function Rt(o,t,e){if(!o)return[""];const s=re(e),r=o.split(`
|
|
2
|
+
`),l=[];for(const i of r){if(!i||s.measureText(i).width<=t){l.push(i||"");continue}const n=i.split(/\s+/);let u="";for(const c of n){const a=u?u+" "+c:c;s.measureText(a).width>t&&u?(l.push(u),u=c):u=a}u&&l.push(u)}return l.length?l:[""]}function B(o,t,e){const s=Rt(o,t,e),r=e*1.3;return Math.max(yt,s.length*r+lt*2)}function ht(o,t={}){const e=document.createElementNS(it,o);for(const[s,r]of Object.entries(t))e.setAttribute(s,String(r));return e}function q(o,t,e,s,r,l,i="start"){const n=l!=null?Rt(o,l,r):[o||""],u=r*1.3,c=n.length*u,a=e+(s-c)/2+u/2,m=ht("text",{x:t,"font-size":r,"font-family":"sans-serif",fill:"#333","text-anchor":i,"dominant-baseline":"central"});for(let d=0;d<n.length;d++){const p=ht("tspan",{x:t,dy:d===0?0:u});d===0&&p.setAttribute("y",a),p.textContent=n[d],m.appendChild(p)}return m}function D(o,t,e,s,r){return ht("rect",{x:o,y:t,width:e,height:s,fill:r,stroke:"none"})}function E(o,t,e,s){return ht("line",{x1:o,y1:t,x2:e,y2:s,stroke:se,"stroke-width":Wt})}function mt(o,t,e){if(e&&e.length===t)return e.map(r=>o*r);const s=o/t;return Array(t).fill(s)}function x(o,t,e){if(!o)return 0;const s=e-X*2;switch(o.type){case"InsertNode":return wt+x(o.followElement,t,e);case"Placeholder":return 0;case"TaskNode":case"InputNode":case"OutputNode":{let r=o.text||"";return o.type==="InputNode"&&(r="▶ "+r),o.type==="OutputNode"&&(r="◀ "+r),B(r,s,t)+x(o.followElement,t,e)}case"InsertCase":return B(o.text||"",s,t)+x(o.followElement,t,e);case"BranchNode":{const r=B(o.text||"",s,t),l=t*1.3+lt,i=t*1.3+lt,n=r+l+i,u=mt(e,2,o.columnWidths),c=x(o.trueChild,t,u[0]),a=x(o.falseChild,t,u[1]);return n+Math.max(c,a)+x(o.followElement,t,e)}case"CaseNode":{const r=o.cases.length+(o.defaultOn?1:0),l=mt(e,r,o.columnWidths),i=B(o.text||"",s,t),n=t*1.3+lt,u=i+n;let c=0;for(let a=0;a<o.cases.length;a++)c=Math.max(c,x(o.cases[a],t,l[a]));return o.defaultOn&&o.defaultNode&&(c=Math.max(c,x(o.defaultNode,t,l[r-1]))),u+c+x(o.followElement,t,e)}case"HeadLoopNode":case"CountLoopNode":{const r=e-w,l=B(o.text||"",s,t),i=x(o.child,t,r),n=Math.max(i,l*.5);return l+n+x(o.followElement,t,e)}case"FootLoopNode":{const r=e-w,l=B(o.text||"",s,t),i=x(o.child,t,r);return Math.max(i,l*.5)+l+x(o.followElement,t,e)}case"FunctionNode":{const r=e-w;let l=o.text||"";o.parameters&&o.parameters.length>0?l+="("+o.parameters.map(a=>a.parName||"").join(", ")+")":l+="()",l+=" {";const i=B(l,s,t),n=x(o.child,t,r),u=Math.max(n,i*.5),c=yt*.6;return i+u+c+x(o.followElement,t,e)}case"TryCatchNode":{const r=e-w,l=B("Try",s,t);let i="Catch";o.text&&(i+=" ("+o.text+")");const n=B(i,s,t),u=x(o.tryChild,t,r),c=Math.max(u,l*.5),a=x(o.catchChild,t,r),m=Math.max(a,n*.5);return l+c+n+m+x(o.followElement,t,e)}default:return 0}}function A(o,t,e,s,r,l){if(!o)return{elements:[],height:0};const i=s-X*2,n=[];switch(o.type){case"InsertNode":{const u=wt,c=A(o.followElement,t,e+u,s,r,l?l-u:void 0);return{elements:c.elements,height:u+c.height}}case"Placeholder":return{elements:[],height:0};case"TaskNode":case"InputNode":case"OutputNode":{const u=et(o.type);let c=o.text||"";o.type==="InputNode"&&(c="▶ "+c),o.type==="OutputNode"&&(c="◀ "+c);const a=B(c,i,r),m=x(o.followElement,r,s),d=a+m,p=l!=null&&l>d?a+(l-d):a;n.push(D(t,e,s,p,u)),n.push(E(t,e,t+s,e)),n.push(E(t,e,t,e+p)),n.push(q(c,t+X,e,a,r,i));const h=l!=null?l-p:void 0,f=A(o.followElement,t,e+p,s,r,h);return{elements:n.concat(f.elements),height:p+f.height}}case"InsertCase":{const u=et(o.type),c=B(o.text||"",i,r),a=x(o.followElement,r,s),m=c+a,d=l!=null&&l>m?c+(l-m):c;n.push(D(t,e,s,d,u)),n.push(E(t,e,t,e+d)),n.push(q(o.text||"",t+X,e,c,r,i));const p=l!=null?l-d:void 0,h=A(o.followElement,t,e+d,s,r,p);return{elements:n.concat(h.elements),height:d+h.height}}case"BranchNode":{const u=et(o.type),c=B(o.text||"",i,r),a=r*1.3+lt,m=r*1.3+lt,d=c+a+m,p=mt(s,2,o.columnWidths),h=t+p[0];n.push(D(t,e,s,d,u)),n.push(E(t,e,t+s,e)),n.push(E(t,e,t,e+d)),n.push(q(o.text||"",t+s/2,e,c,r,i,"middle"));const f=e+c+a;n.push(E(t,e+c,h,f)),n.push(E(t+s,e+c,h,f));const b=r*.8;n.push(q("Wahr",t+X,f,m,b,null)),n.push(q("Falsch",t+s-X,f,m,b,null,"end")),n.push(E(h,f,h,e+d));const _=x(o.trueChild,r,p[0]),g=x(o.falseChild,r,p[1]),C=x(o.followElement,r,s),L=Math.max(_,g),I=l!=null&&l>d+L+C?l-d-L-C:0,N=L+I,y=A(o.trueChild,t,e+d,p[0],r,N);n.push(...y.elements);const J=A(o.falseChild,h,e+d,p[1],r,N);n.push(...J.elements),n.push(E(h,e+d,h,e+d+N));const S=d+N,dt=l!=null?l-S:void 0,Et=A(o.followElement,t,e+S,s,r,dt);return{elements:n.concat(Et.elements),height:S+Et.height}}case"CaseNode":{const u=et(o.type),c=o.cases.length+(o.defaultOn?1:0),a=mt(s,c,o.columnWidths),m=B(o.text||"",i,r),d=r*1.3+lt,p=m+d;n.push(D(t,e,s,p,u)),n.push(E(t,e,t+s,e)),n.push(E(t,e,t,e+p)),n.push(q(o.text||"",t+s/2,e,m,r,i,"middle"));const h=[0];for(let N=0;N<c;N++)h.push(h[N]+a[N]);if(o.defaultOn){const N=t+h[c-1];n.push(E(t,e+m,N,e+p)),n.push(E(t+s,e+m,N,e+p));for(let y=1;y<c-1;y++){const J=t+h[y],S=h[y]/h[c-1],dt=e+m+d*S;n.push(E(J,dt,J,e+p))}}else{n.push(E(t,e+m,t+s,e+p));for(let N=1;N<c;N++){const y=t+h[N],J=h[N]/s,S=e+m+d*J;n.push(E(y,S,y,e+p))}}let f=0;for(let N=0;N<o.cases.length;N++){const y=x(o.cases[N],r,a[N]);f=Math.max(f,y)}if(o.defaultOn&&o.defaultNode){const N=x(o.defaultNode,r,a[c-1]);f=Math.max(f,N)}const b=x(o.followElement,r,s),_=l!=null&&l>p+f+b?l-p-f-b:0;f+=_;let g=t;for(let N=0;N<o.cases.length;N++){const y=A(o.cases[N],g,e+p,a[N],r,f);n.push(...y.elements),N>0&&n.push(E(g,e+p,g,e+p+f)),g+=a[N]}if(o.defaultOn&&o.defaultNode){const N=A(o.defaultNode,g,e+p,a[c-1],r,f);n.push(...N.elements),n.push(E(g,e+p,g,e+p+f))}const C=p+f,L=l!=null?l-C:void 0,I=A(o.followElement,t,e+C,s,r,L);return{elements:n.concat(I.elements),height:C+I.height}}case"HeadLoopNode":case"CountLoopNode":{const u=et(o.type),c=B(o.text||"",i,r);n.push(D(t,e,s,c,u)),n.push(E(t,e,t+s,e)),n.push(E(t,e,t,e+c)),n.push(q(o.text||"",t+X,e,c,r,i));const a=s-w,m=x(o.child,r,a),d=Math.max(m,c*.5);n.push(D(t,e+c,w,d,u)),n.push(E(t,e+c,t,e+c+d)),n.push(E(t+w,e+c,t+w,e+c+d));const p=A(o.child,t+w,e+c,a,r);n.push(...p.elements);const h=c+d,f=l!=null?l-h:void 0,b=A(o.followElement,t,e+h,s,r,f);return{elements:n.concat(b.elements),height:h+b.height}}case"FootLoopNode":{const u=et(o.type),c=s-w,a=B(o.text||"",i,r),m=x(o.child,r,c),d=Math.max(m,a*.5);n.push(D(t,e,w,d,u)),n.push(E(t,e,t+s,e)),n.push(E(t,e,t,e+d)),n.push(E(t+w,e,t+w,e+d));const p=A(o.child,t+w,e,c,r);n.push(...p.elements),n.push(D(t,e+d,s,a,u)),n.push(E(t+w,e+d,t+s,e+d)),n.push(E(t,e+d,t,e+d+a)),n.push(q(o.text||"",t+X,e+d,a,r,i));const h=d+a,f=l!=null?l-h:void 0,b=A(o.followElement,t,e+h,s,r,f);return{elements:n.concat(b.elements),height:h+b.height}}case"FunctionNode":{const u=et(o.type);let c=o.text||"";if(o.parameters&&o.parameters.length>0){const C=o.parameters.map(L=>L.parName||"").join(", ");c+="("+C+")"}else c+="()";c+=" {";const a=B(c,i,r);n.push(D(t,e,s,a,u)),n.push(E(t,e,t+s,e)),n.push(E(t,e,t,e+a)),n.push(q(c,t+X,e,a,r,i));const m=s-w,d=x(o.child,r,m),p=Math.max(d,a*.5);n.push(D(t,e+a,w,p,u)),n.push(E(t,e+a,t,e+a+p)),n.push(E(t+w,e+a,t+w,e+a+p));const h=A(o.child,t+w,e+a,m,r);n.push(...h.elements);const f=yt*.6;n.push(D(t,e+a+p,s,f,u)),n.push(E(t+w,e+a+p,t+s,e+a+p)),n.push(E(t,e+a+p,t,e+a+p+f)),n.push(q("}",t+X,e+a+p,f,r,null));const b=a+p+f,_=l!=null?l-b:void 0,g=A(o.followElement,t,e+b,s,r,_);return{elements:n.concat(g.elements),height:b+g.height}}case"TryCatchNode":{const u=et(o.type),c=s-w,a=B("Try",i,r);n.push(D(t,e,s,a,u)),n.push(E(t,e,t+s,e)),n.push(E(t,e,t,e+a)),n.push(q("Try",t+X,e,a,r,null));const m=x(o.tryChild,r,c),d=Math.max(m,a*.5);n.push(D(t,e+a,w,d,u)),n.push(E(t,e+a,t,e+a+d)),n.push(E(t+w,e+a,t+w,e+a+d));const p=A(o.tryChild,t+w,e+a,c,r);n.push(...p.elements);const h=e+a+d;let f="Catch";o.text&&(f+=" ("+o.text+")");const b=B(f,i,r);n.push(D(t,h,s,b,u)),n.push(E(t+w,h,t+s,h)),n.push(E(t,h,t,h+b)),n.push(q(f,t+X,h,b,r,i));const _=x(o.catchChild,r,c),g=Math.max(_,b*.5);n.push(D(t,h+b,w,g,u)),n.push(E(t,h+b,t,h+b+g)),n.push(E(t+w,h+b,t+w,h+b+g)),n.push(E(t,h+b+g,t+w,h+b+g));const C=A(o.catchChild,t+w,h+b,c,r);n.push(...C.elements);const L=a+d+b+g,I=l!=null?l-L:void 0,N=A(o.followElement,t,e+L,s,r,I);return{elements:n.concat(N.elements),height:L+N.height}}default:return{elements:[],height:0}}}function Tt(o,t={}){const e=t.width||600,s=t.fontSize||14;t.colorMode&&Ot[t.colorMode]&&(Mt=t.colorMode);const l=x(o,s,e)||40,i=Wt,n=ht("svg",{xmlns:it,viewBox:`${-i} ${-i} ${e+i*2} ${l+i*2}`,preserveAspectRatio:"xMinYMin meet"});n.style.display="block",n.style.width="100%",n.style.height="auto";const u=A(o,0,0,e,s);for(const c of u.elements)n.appendChild(c);return n.appendChild(E(e,0,e,u.height)),n.appendChild(E(0,u.height,e,u.height)),n}const gt={if:"falls",else:"sonst",repeat:"wiederhole",while:"solange",for:"für",switch:"unterscheide",case:"fall",function:"funktion",try:"versuche",catch:"fange",input:"eingabe",output:"ausgabe",true:"Wahr",false:"Falsch",default:"Sonst"},Pt={if:"if",else:"else",repeat:"repeat",while:"while",for:"for",switch:"switch",case:"case",function:"function",try:"try",catch:"catch",input:"input",output:"output",true:"True",false:"False",default:"Default"};function V(o){return o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}let Ft=0;function $(){return"__pseudo_"+ ++Ft}function M(o){return{id:$(),type:"InsertNode",followElement:o}}function bt(){return{type:"Placeholder"}}function Lt(o){const t=o.match(/^(.*?)\s*\[([0-9.,\s]+)\]\s*$/);if(t){const e=t[1].trim(),s=t[2].split(",").map(r=>parseFloat(r.trim())).filter(r=>!isNaN(r));return{text:e,columnWidths:s.length>0?s:null}}return{text:o,columnWidths:null}}function ne(o){const t=o.split(`
|
|
3
|
+
`),e=[];for(const s of t){const r=s.trimEnd();if(r===""||r.startsWith("#"))continue;const l=s.replace(/\t/g," "),i=l.length-l.trimStart().length;e.push({text:r.trim(),indent:i})}return e}function Dt(o,t){const e=[];let s=0;for(;s<o.length;){const r=o[s];if(r.indent<t)break;if(r.indent>t){s++;continue}const l=[];for(s++;s<o.length&&o[s].indent>t;)l.push(o[s]),s++;e.push({text:r.text,indent:r.indent,children:l})}return e}function Ht(o){return o.endsWith(":")?o.slice(0,-1).trimEnd():o}function Q(o,t,e){const s=Dt(o,t);if(s.length===0)return M(bt());const r=V(e.try),l=V(e.catch),i=V(e.if),n=V(e.else),u=V(e.repeat),c=V(e.while),a=V(e.for),m=V(e.switch),d=V(e.case),p=V(e.function),h=V(e.input),f=V(e.output),b=new RegExp(`^${r}\\s*:$`,"i"),_=new RegExp(`^${l}\\s+`,"i"),g=new RegExp(`^${i}\\s+`,"i"),C=new RegExp(`^${n}\\s*:$`,"i"),L=new RegExp(`^${u}\\s*:$`,"i"),I=new RegExp(`^${c}\\s+`,"i"),N=new RegExp(`^${u}\\s+${a}\\s+(.+)\\s*:$`,"i"),y=new RegExp(`^${u}\\s+${c}\\s+(.+)\\s*:$`,"i"),J=new RegExp(`^${p}\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*:$`,"i"),S=new RegExp(`^${m}\\s+(.+)\\s*:$`,"i"),dt=new RegExp(`^${d}\\s+(.+)\\s*:$`,"i"),Et=new RegExp(`^${h}\\s*\\(\\s*"?([^"]*)"?\\s*\\)$`,"i"),ge=new RegExp(`^${f}\\s*\\(\\s*"?([^"]*)"?\\s*\\)$`,"i"),Z=[];for(const W of s)Z.push({block:W,_skip:!1});for(let W=0;W<Z.length-1;W++){const K=Z[W].block.text,O=Z[W+1].block.text;(b.test(K)&&_.test(O)||g.test(K)&&C.test(O)||L.test(K)&&I.test(O)&&!O.endsWith(":"))&&(Z[W+1]._skip=!0)}let k=M(null);for(let W=Z.length-1;W>=0;W--){const K=Z[W].block,O=K.text;if(Z[W]._skip)continue;const z=W+1<Z.length?Z[W+1].block:null;if(b.test(O)&&z&&_.test(z.text)){const R=t+4,P=Q(K.children,R,e),F=Ht(z.text.replace(_,"")),U=Q(z.children,R,e);k=M({id:$(),type:"TryCatchNode",text:F,tryChild:P,catchChild:U,followElement:k});continue}if(g.test(O)&&z&&C.test(z.text)){const R=Ht(O.replace(g,"")),{text:P,columnWidths:F}=Lt(R),U=t+4,rt=Q(K.children,U,e),nt=Q(z.children,U,e),tt={id:$(),type:"BranchNode",text:P,trueChild:rt,falseChild:nt,followElement:k};F&&(tt.columnWidths=F),k=M(tt);continue}if(g.test(O)){const R=Ht(O.replace(g,"")),{text:P,columnWidths:F}=Lt(R),U=t+4,rt=Q(K.children,U,e),nt={id:$(),type:"BranchNode",text:P,trueChild:rt,falseChild:M(bt()),followElement:k};F&&(nt.columnWidths=F),k=M(nt);continue}if(L.test(O)&&z&&I.test(z.text)&&!z.text.endsWith(":")){const R=z.text.replace(I,"").trim(),P=t+4,F=Q(K.children,P,e);k=M({id:$(),type:"FootLoopNode",text:R,child:F,followElement:k});continue}const Qt=O.match(N);if(Qt){const R=t+4,P=Q(K.children,R,e);k=M({id:$(),type:"CountLoopNode",text:Qt[1],child:P,followElement:k});continue}const Zt=O.match(y);if(Zt){const R=t+4,P=Q(K.children,R,e);k=M({id:$(),type:"HeadLoopNode",text:Zt[1],child:P,followElement:k});continue}const vt=O.match(J);if(vt){const R=vt[1],P=vt[2].trim(),F=P?P.split(",").map((tt,pt)=>({pos:String(pt*3),parName:tt.trim()})):[],U=t+4,rt=Q(K.children,U,e);k=M({id:$(),type:"FunctionNode",text:R,parameters:F,child:rt,followElement:k});continue}const St=O.match(S);if(St){const R=St[1],{text:P,columnWidths:F}=Lt(R),U=t+4,rt=Dt(K.children,U),nt=[];let tt=null,pt=!1;for(const Ct of rt){const oe=Ct.text.match(dt);if(oe){const At=U+4,Bt=Q(Ct.children,At,e);nt.push({id:$(),type:"InsertCase",text:oe[1].replace(/^"(.*)"$/,"$1"),followElement:Bt})}else if(C.test(Ct.text)){pt=!0;const At=U+4,Bt=Q(Ct.children,At,e);tt={id:$(),type:"InsertCase",text:e.default,followElement:Bt}}}tt||(tt={id:$(),type:"InsertCase",text:e.default,followElement:M(bt())});const ee={id:$(),type:"CaseNode",text:P,defaultOn:pt,defaultNode:tt,cases:nt,followElement:k};F&&(ee.columnWidths=F),k=M(ee);continue}const zt=O.match(Et);if(zt){k=M({id:$(),type:"InputNode",text:zt[1],followElement:k});continue}const te=O.match(ge);if(te){k=M({id:$(),type:"OutputNode",text:te[1],followElement:k});continue}k=M({id:$(),type:"TaskNode",text:O,followElement:k})}return k}function Nt(o,t=gt){Ft=0;const e=ne(o);if(e.length===0)return M(bt());const s=Math.min(...e.map(r=>r.indent));return Q(e,s,t)}const $t={python:{InputNode:{pre:"",post:` = input("Eingabe")
|
|
4
|
+
`},OutputNode:{pre:"print(",post:`)
|
|
5
|
+
`},TaskNode:{pre:"",post:`
|
|
6
|
+
`},BranchNode:{pre:"if ",post:`:
|
|
7
|
+
`,between:`else:
|
|
8
|
+
`},TryCatchNode:{pre:`try:
|
|
9
|
+
`,between:"except ",post:`:
|
|
10
|
+
`},CountLoopNode:{pre:"for ",post:`:
|
|
11
|
+
`},HeadLoopNode:{pre:"while ",post:`:
|
|
12
|
+
`},FootLoopNode:{prepre:`while True:
|
|
13
|
+
`,pre:" if not ",post:`:
|
|
14
|
+
break
|
|
15
|
+
`},FunctionNode:{pre:"def ",between:"(",post:`):
|
|
16
|
+
`},CaseNode:{pre:"if ",post:`:
|
|
17
|
+
`},InsertCase:{preNormal:"elif ",preDefault:"else",post:`:
|
|
18
|
+
`,postpost:`
|
|
19
|
+
`},leftBracket:"",rightBracket:"",pseudoSwitch:!0},java:{InputNode:{pre:"",post:` = System.console().readLine();
|
|
20
|
+
`},OutputNode:{pre:"System.out.println(",post:`);
|
|
21
|
+
`},TaskNode:{pre:"",post:`;
|
|
22
|
+
`},BranchNode:{pre:"if (",post:")",between:`} else {
|
|
23
|
+
`},TryCatchNode:{pre:"try",between:"catch (",post:")"},CountLoopNode:{pre:"for (",post:")"},HeadLoopNode:{pre:"while (",post:")"},FootLoopNode:{prepre:"do",pre:"while (",post:`);
|
|
24
|
+
`},FunctionNode:{pre:"public void ",between:"(",post:")"},CaseNode:{pre:"switch (",post:")"},InsertCase:{preNormal:"case ",preDefault:"default",post:`:
|
|
25
|
+
`,postpost:`break;
|
|
26
|
+
`},leftBracket:"{",rightBracket:"}",pseudoSwitch:!1},javascript:{InputNode:{pre:"",post:` = prompt("Eingabe");
|
|
27
|
+
`},OutputNode:{pre:"console.log(",post:`);
|
|
28
|
+
`},TaskNode:{pre:"",post:`;
|
|
29
|
+
`},BranchNode:{pre:"if (",post:")",between:`} else {
|
|
30
|
+
`},TryCatchNode:{pre:"try",between:"catch (",post:")"},CountLoopNode:{pre:"for (",post:")"},HeadLoopNode:{pre:"while (",post:")"},FootLoopNode:{prepre:"do",pre:"while (",post:`);
|
|
31
|
+
`},FunctionNode:{pre:"function ",between:"(",post:")"},CaseNode:{pre:"switch (",post:")"},InsertCase:{preNormal:"case ",preDefault:"default",post:`:
|
|
32
|
+
`,postpost:`break;
|
|
33
|
+
`},leftBracket:"{",rightBracket:"}",pseudoSwitch:!1}};function H(o){return" ".repeat(o)}function jt(o,t="python"){const e=$t[t.toLowerCase()];if(!e)throw new Error(`Unsupported language: ${t}. Supported: ${Object.keys($t).join(", ")}`);return j(o,0,e,t.toLowerCase()).join("")}function j(o,t,e,s){if(!o)return[];if(o.type==="InsertNode"||o.type==="Placeholder")return j(o.followElement,t,e,s);const r=o.text||"",l=[];switch(o.type){case"TaskNode":l.push(H(t)+e.TaskNode.pre+r+e.TaskNode.post);break;case"InputNode":l.push(H(t)+e.InputNode.pre+r+e.InputNode.post);break;case"OutputNode":l.push(H(t)+e.OutputNode.pre+r+e.OutputNode.post);break;case"BranchNode":{l.push(H(t)+e.BranchNode.pre+r+e.BranchNode.post+(e.leftBracket?" "+e.leftBracket+`
|
|
34
|
+
`:"")),l.push(...j(o.trueChild,t+1,e,s)),l.push(H(t)+e.BranchNode.between),l.push(...j(o.falseChild,t+1,e,s)),e.rightBracket&&l.push(H(t)+e.rightBracket+`
|
|
35
|
+
`);break}case"HeadLoopNode":l.push(H(t)+e.HeadLoopNode.pre+r+e.HeadLoopNode.post+(e.leftBracket?" "+e.leftBracket+`
|
|
36
|
+
`:"")),l.push(...j(o.child,t+1,e,s)),e.rightBracket&&l.push(H(t)+e.rightBracket+`
|
|
37
|
+
`);break;case"CountLoopNode":l.push(H(t)+e.CountLoopNode.pre+r+e.CountLoopNode.post+(e.leftBracket?" "+e.leftBracket+`
|
|
38
|
+
`:"")),l.push(...j(o.child,t+1,e,s)),e.rightBracket&&l.push(H(t)+e.rightBracket+`
|
|
39
|
+
`);break;case"FootLoopNode":{l.push(H(t)+e.FootLoopNode.prepre+(e.leftBracket?" "+e.leftBracket+`
|
|
40
|
+
`:"")),l.push(...j(o.child,t+1,e,s)),e.pseudoSwitch?l.push(H(t)+e.FootLoopNode.pre+r+e.FootLoopNode.post):(e.rightBracket&&l.push(H(t)+e.rightBracket+" "),l.push(e.FootLoopNode.pre+r+e.FootLoopNode.post));break}case"FunctionNode":{const i=(o.parameters||[]).map(n=>n.parName).join(", ");l.push(H(t)+e.FunctionNode.pre+r+e.FunctionNode.between+i+e.FunctionNode.post+(e.leftBracket?" "+e.leftBracket+`
|
|
41
|
+
`:"")),l.push(...j(o.child,t+1,e,s)),e.rightBracket&&l.push(H(t)+e.rightBracket+`
|
|
42
|
+
`);break}case"TryCatchNode":{l.push(H(t)+e.TryCatchNode.pre+(e.leftBracket?" "+e.leftBracket+`
|
|
43
|
+
`:"")),l.push(...j(o.tryChild,t+1,e,s)),l.push(H(t)+(e.rightBracket?e.rightBracket+" ":"")+e.TryCatchNode.between+r+e.TryCatchNode.post+(e.leftBracket?" "+e.leftBracket+`
|
|
44
|
+
`:"")),l.push(...j(o.catchChild,t+1,e,s)),e.rightBracket&&l.push(H(t)+e.rightBracket+`
|
|
45
|
+
`);break}case"CaseNode":{if(e.pseudoSwitch){let i=!0;for(const n of o.cases||[])if(n.type==="InsertCase"){const u=i?"if ":e.InsertCase.preNormal;l.push(H(t)+u+r+" == "+n.text+e.InsertCase.post),l.push(...j(n.followElement,t+1,e,s)),i=!1}o.defaultOn&&o.defaultNode&&(l.push(H(t)+e.InsertCase.preDefault+e.InsertCase.post),l.push(...j(o.defaultNode.followElement,t+1,e,s)))}else{l.push(H(t)+e.CaseNode.pre+r+e.CaseNode.post+(e.leftBracket?" "+e.leftBracket+`
|
|
46
|
+
`:""));for(const i of o.cases||[])i.type==="InsertCase"&&(l.push(H(t+1)+e.InsertCase.preNormal+i.text+e.InsertCase.post),l.push(...j(i.followElement,t+2,e,s)),e.InsertCase.postpost&&l.push(H(t+2)+e.InsertCase.postpost));o.defaultOn&&o.defaultNode&&(l.push(H(t+1)+e.InsertCase.preDefault+e.InsertCase.post),l.push(...j(o.defaultNode.followElement,t+2,e,s)),s==="java"&&l.push(H(t+2)+e.InsertCase.postpost)),e.rightBracket&&l.push(H(t)+e.rightBracket+`
|
|
47
|
+
`)}break}}return l.push(...j(o.followElement,t,e,s)),l}const le=" ";function Gt(o,t=gt){const e=[];return v(o,0,e,t),e.join(`
|
|
48
|
+
`)}function G(o){return le.repeat(o)}function Jt(o){return o.columnWidths&&o.columnWidths.length>0?" ["+o.columnWidths.join(", ")+"]":""}function v(o,t,e,s){if(o)switch(o.type){case"InsertNode":v(o.followElement,t,e,s);return;case"Placeholder":return;case"TaskNode":e.push(G(t)+(o.text||"")),v(o.followElement,t,e,s);return;case"InputNode":e.push(G(t)+s.input+'("'+(o.text||"")+'")'),v(o.followElement,t,e,s);return;case"OutputNode":e.push(G(t)+s.output+'("'+(o.text||"")+'")'),v(o.followElement,t,e,s);return;case"BranchNode":e.push(G(t)+s.if+" "+(o.text||"")+Jt(o)+":"),v(o.trueChild,t+1,e,s),e.push(G(t)+s.else+":"),v(o.falseChild,t+1,e,s),v(o.followElement,t,e,s);return;case"CaseNode":{if(e.push(G(t)+s.switch+" "+(o.text||"")+Jt(o)+":"),o.cases)for(const r of o.cases)e.push(G(t+1)+s.case+" "+r.text+":"),v(r.followElement,t+2,e,s);o.defaultOn&&o.defaultNode&&(e.push(G(t+1)+s.else+":"),v(o.defaultNode.followElement,t+2,e,s)),v(o.followElement,t,e,s);return}case"HeadLoopNode":e.push(G(t)+s.repeat+" "+s.while+" "+(o.text||"")+":"),v(o.child,t+1,e,s),v(o.followElement,t,e,s);return;case"CountLoopNode":e.push(G(t)+s.repeat+" "+s.for+" "+(o.text||"")+":"),v(o.child,t+1,e,s),v(o.followElement,t,e,s);return;case"FootLoopNode":e.push(G(t)+s.repeat+":"),v(o.child,t+1,e,s),e.push(G(t)+s.while+" "+(o.text||"")),v(o.followElement,t,e,s);return;case"FunctionNode":{const r=(o.parameters||[]).map(l=>l.parName).join(", ");e.push(G(t)+s.function+" "+(o.text||"")+"("+r+"):"),v(o.child,t+1,e,s),v(o.followElement,t,e,s);return}case"TryCatchNode":e.push(G(t)+s.try+":"),v(o.tryChild,t+1,e,s),e.push(G(t)+s.catch+" "+(o.text||"")+":"),v(o.catchChild,t+1,e,s),v(o.followElement,t,e,s);return;default:return}}let ce=0;function T(){return"__ed_"+Date.now().toString(36)+"_"+ ++ce}function ot(o){return o?JSON.parse(JSON.stringify(o)):null}function ct(o,t){if(!o)return null;if(o.id===t)return o;for(const e of["followElement","trueChild","falseChild","child","tryChild","catchChild"])if(o[e]){const s=ct(o[e],t);if(s)return s}if(o.cases)for(const e of o.cases){const s=ct(e,t);if(s)return s}if(o.defaultNode){const e=ct(o.defaultNode,t);if(e)return e}return null}function ut(o,t,e=null,s=null,r=null){if(!o)return null;if(o.id===t)return{parent:e,key:s,index:r};for(const l of["followElement","trueChild","falseChild","child","tryChild","catchChild"])if(o[l]){const i=ut(o[l],t,o,l);if(i)return i}if(o.cases)for(let l=0;l<o.cases.length;l++){const i=ut(o.cases[l],t,o,"cases",l);if(i)return i}if(o.defaultNode){const l=ut(o.defaultNode,t,o,"defaultNode");if(l)return l}return null}function ae(o){const t=T(),e={id:T(),type:"InsertNode",followElement:{type:"Placeholder"}};switch(o){case"TaskNode":return{id:t,type:"TaskNode",text:"Anweisung",followElement:null};case"InputNode":return{id:t,type:"InputNode",text:"Eingabe",followElement:null};case"OutputNode":return{id:t,type:"OutputNode",text:"Ausgabe",followElement:null};case"BranchNode":return{id:t,type:"BranchNode",text:"Bedingung",trueChild:{...e,id:T()},falseChild:{id:T(),type:"InsertNode",followElement:{type:"Placeholder"}},followElement:null};case"CaseNode":return{id:t,type:"CaseNode",text:"Variable",defaultOn:!0,defaultNode:{id:T(),type:"InsertCase",text:"Sonst",followElement:{id:T(),type:"InsertNode",followElement:{type:"Placeholder"}}},cases:[{id:T(),type:"InsertCase",text:"Fall 1",followElement:{id:T(),type:"InsertNode",followElement:{type:"Placeholder"}}},{id:T(),type:"InsertCase",text:"Fall 2",followElement:{id:T(),type:"InsertNode",followElement:{type:"Placeholder"}}}],followElement:null};case"HeadLoopNode":return{id:t,type:"HeadLoopNode",text:"Bedingung",child:{...e,id:T()},followElement:null};case"CountLoopNode":return{id:t,type:"CountLoopNode",text:"i = 1 bis 10",child:{id:T(),type:"InsertNode",followElement:{type:"Placeholder"}},followElement:null};case"FootLoopNode":return{id:t,type:"FootLoopNode",text:"Bedingung",child:{id:T(),type:"InsertNode",followElement:{type:"Placeholder"}},followElement:null};case"FunctionNode":return{id:t,type:"FunctionNode",text:"funktion",parameters:[{pos:"0",parName:"param"}],child:{id:T(),type:"InsertNode",followElement:{type:"Placeholder"}},followElement:null};case"TryCatchNode":return{id:t,type:"TryCatchNode",text:"Exception e",tryChild:{id:T(),type:"InsertNode",followElement:{type:"Placeholder"}},catchChild:{id:T(),type:"InsertNode",followElement:{type:"Placeholder"}},followElement:null};default:return{id:t,type:"TaskNode",text:o,followElement:null}}}function Yt(o,t,e){const s=ot(o),r=ct(s,t);if(!r)return s;const l=ae(e);if(r.type==="InsertNode")l.followElement=r.followElement,r.followElement=l;else if(r.type==="Placeholder"){const i=ut(s,t);if(i){const n={id:T(),type:"InsertNode",followElement:l};l.followElement={id:T(),type:"InsertNode",followElement:{type:"Placeholder"}},i.index!=null?i.parent[i.key][i.index]=n:i.parent[i.key]=n}}return s}function ie(o,t){const e=ot(o),s=ut(e,t);if(!s)return e;const r=s.index!=null?s.parent[s.key][s.index]:s.parent[s.key];if(!r)return e;const l=r.followElement||{type:"Placeholder"};return s.index!=null?s.parent[s.key][s.index]=l:s.parent[s.key]=l,e}function ue(o,t,e){const s=ot(o),r=ct(s,t);return r&&(r.text=e),s}function he(o,t,e){if(t===e)return o;let s=ot(o);const r=ut(s,t);if(!r)return s;const l=r.index!=null?r.parent[r.key][r.index]:r.parent[r.key];if(!l)return s;const i=l.followElement||{type:"Placeholder"};r.index!=null?r.parent[r.key][r.index]=i:r.parent[r.key]=i;const n=ct(s,e);return n&&(l.followElement=null,n.type==="InsertNode"&&(l.followElement=n.followElement,n.followElement=l)),s}function de(o){if(!o)return{id:T(),type:"InsertNode",followElement:{id:T(),type:"Placeholder"}};const t=ot(o);return at(t)}function at(o){if(!o)return{id:T(),type:"InsertNode",followElement:{id:T(),type:"Placeholder"}};if(o.type==="InsertNode")return o.followElement=o.followElement?It(o.followElement):{id:T(),type:"Placeholder"},o;if(o.type==="Placeholder")return{id:T(),type:"InsertNode",followElement:o};const t=It(o);return{id:T(),type:"InsertNode",followElement:t}}function It(o){if(!o)return{id:T(),type:"Placeholder"};if(o.type==="InsertNode")return o.followElement=o.followElement?It(o.followElement):{id:T(),type:"Placeholder"},o;if(o.type==="Placeholder")return o;for(const t of["trueChild","falseChild","child","tryChild","catchChild"])o[t]&&(o[t]=at(o[t]));if(o.cases)for(let t=0;t<o.cases.length;t++)o.cases[t]&&o.cases[t].type==="InsertCase"?o.cases[t].followElement=at(o.cases[t].followElement):o.cases[t]=at(o.cases[t]);return o.defaultNode&&(o.defaultNode.type==="InsertCase"?o.defaultNode.followElement=at(o.defaultNode.followElement):o.defaultNode=at(o.defaultNode)),o.followElement?o.followElement=at(o.followElement):o.followElement={id:T(),type:"InsertNode",followElement:{id:T(),type:"Placeholder"}},o}function Kt(o){if(!o)return o;const t=ot(o);function e(s){if(s){s.id||(s.id=T());for(const r of["followElement","trueChild","falseChild","child","tryChild","catchChild"])s[r]&&e(s[r]);s.cases&&s.cases.forEach(e),s.defaultNode&&e(s.defaultNode)}}return e(t),t}function Ut(o){if(!o)return null;const t=ot(o);return st(t)}function st(o){if(!o||o.type==="Placeholder")return null;if(o.type==="InsertNode")return st(o.followElement);for(const t of["trueChild","falseChild","child","tryChild","catchChild"])o[t]&&(o[t]=st(o[t]));return o.cases&&(o.cases=o.cases.map(t=>t&&t.type==="InsertCase"?(t.followElement=st(t.followElement),t):st(t)).filter(Boolean)),o.defaultNode&&(o.defaultNode.type==="InsertCase"?o.defaultNode.followElement=st(o.defaultNode.followElement):o.defaultNode=st(o.defaultNode)),o.followElement=st(o.followElement),delete o.id,_t(o),o}function _t(o){if(o){delete o.id;for(const t of["followElement","trueChild","falseChild","child","tryChild","catchChild"])o[t]&&_t(o[t]);o.cases&&o.cases.forEach(_t),o.defaultNode&&_t(o.defaultNode)}}const kt="rgba(1, 116, 96, 0.2)",Xt="rgba(1, 116, 96, 0.45)",qt=20,pe="rgba(192, 57, 43, 0.25)",fe=[{type:"TaskNode",label:"Task",icon:"▭"},{type:"InputNode",label:"Input",icon:"▶"},{type:"OutputNode",label:"Output",icon:"◀"},{type:"BranchNode",label:"If/Else",icon:"◇"},{type:"CaseNode",label:"Switch",icon:"⊞"},{type:"HeadLoopNode",label:"While",icon:"↻"},{type:"FootLoopNode",label:"Do-While",icon:"↺"},{type:"CountLoopNode",label:"For",icon:"#"},{type:"FunctionNode",label:"Function",icon:"ƒ"},{type:"TryCatchNode",label:"Try/Catch",icon:"⚡"}],me=`
|
|
49
|
+
:host {
|
|
50
|
+
display: block;
|
|
51
|
+
width: 100%;
|
|
52
|
+
font-family: sans-serif;
|
|
53
|
+
--toolbar-bg: #f5f5f5;
|
|
54
|
+
--toolbar-border: #d6d6d6;
|
|
55
|
+
--btn-bg: #fff;
|
|
56
|
+
--btn-hover: #b5e3d9;
|
|
57
|
+
--btn-active: #b5e3d9;
|
|
58
|
+
--danger: #c0392b;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.toolbar {
|
|
62
|
+
display: flex;
|
|
63
|
+
flex-wrap: wrap;
|
|
64
|
+
gap: 4px;
|
|
65
|
+
padding: 6px 8px;
|
|
66
|
+
background: var(--toolbar-bg);
|
|
67
|
+
border: 1px solid var(--toolbar-border);
|
|
68
|
+
border-radius: 4px 4px 0 0;
|
|
69
|
+
align-items: center;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.toolbar button {
|
|
73
|
+
display: inline-flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
gap: 4px;
|
|
76
|
+
padding: 4px 10px;
|
|
77
|
+
border: 1px solid var(--toolbar-border);
|
|
78
|
+
border-radius: 3px;
|
|
79
|
+
background: var(--btn-bg);
|
|
80
|
+
cursor: pointer;
|
|
81
|
+
font-size: 13px;
|
|
82
|
+
font-family: inherit;
|
|
83
|
+
white-space: nowrap;
|
|
84
|
+
user-select: none;
|
|
85
|
+
}
|
|
86
|
+
.toolbar button:hover { background: var(--btn-hover); }
|
|
87
|
+
.toolbar button.active { background: var(--btn-active); border-color: #017460; }
|
|
88
|
+
.toolbar button.danger { color: var(--danger); border-color: var(--danger); }
|
|
89
|
+
.toolbar button.danger:hover { background: #fde; }
|
|
90
|
+
.toolbar button.danger.active { background: #fcc; }
|
|
91
|
+
|
|
92
|
+
.toolbar .sep {
|
|
93
|
+
width: 1px;
|
|
94
|
+
height: 24px;
|
|
95
|
+
background: var(--toolbar-border);
|
|
96
|
+
margin: 0 4px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.toolbar select, .toolbar input[type="number"] {
|
|
100
|
+
padding: 3px 6px;
|
|
101
|
+
border: 1px solid var(--toolbar-border);
|
|
102
|
+
border-radius: 3px;
|
|
103
|
+
background: var(--btn-bg);
|
|
104
|
+
font-size: 13px;
|
|
105
|
+
font-family: inherit;
|
|
106
|
+
}
|
|
107
|
+
.toolbar label {
|
|
108
|
+
font-size: 12px;
|
|
109
|
+
color: #3c3c3c;
|
|
110
|
+
display: inline-flex;
|
|
111
|
+
align-items: center;
|
|
112
|
+
gap: 4px;
|
|
113
|
+
white-space: nowrap;
|
|
114
|
+
}
|
|
115
|
+
.toolbar input[type="number"] {
|
|
116
|
+
width: 52px;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.editor-area {
|
|
120
|
+
position: relative;
|
|
121
|
+
border-left: 1px solid var(--toolbar-border);
|
|
122
|
+
border-right: 1px solid var(--toolbar-border);
|
|
123
|
+
min-height: 60px;
|
|
124
|
+
overflow: hidden;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.editor-area svg { cursor: default; }
|
|
128
|
+
.editor-area.mode-insert svg { cursor: crosshair; }
|
|
129
|
+
.editor-area.mode-delete svg { cursor: not-allowed; }
|
|
130
|
+
|
|
131
|
+
.text-overlay {
|
|
132
|
+
position: absolute;
|
|
133
|
+
display: flex;
|
|
134
|
+
gap: 4px;
|
|
135
|
+
padding: 2px;
|
|
136
|
+
z-index: 10;
|
|
137
|
+
}
|
|
138
|
+
.text-overlay textarea {
|
|
139
|
+
flex: 1;
|
|
140
|
+
font-size: 14px;
|
|
141
|
+
font-family: inherit;
|
|
142
|
+
padding: 2px 6px;
|
|
143
|
+
border: 2px solid #017460;
|
|
144
|
+
border-radius: 3px;
|
|
145
|
+
outline: none;
|
|
146
|
+
min-width: 60px;
|
|
147
|
+
resize: none;
|
|
148
|
+
line-height: 1.4;
|
|
149
|
+
}
|
|
150
|
+
.text-overlay button {
|
|
151
|
+
padding: 2px 8px;
|
|
152
|
+
border: 1px solid #d6d6d6;
|
|
153
|
+
border-radius: 3px;
|
|
154
|
+
cursor: pointer;
|
|
155
|
+
font-size: 14px;
|
|
156
|
+
}
|
|
157
|
+
.text-overlay .ok { background: #b5e3d9; }
|
|
158
|
+
.text-overlay .cancel { background: #f8d7da; }
|
|
159
|
+
|
|
160
|
+
.pseudocode-area {
|
|
161
|
+
border: 1px solid var(--toolbar-border);
|
|
162
|
+
border-radius: 0 0 4px 4px;
|
|
163
|
+
}
|
|
164
|
+
.pseudocode-area textarea {
|
|
165
|
+
display: block;
|
|
166
|
+
width: 100%;
|
|
167
|
+
min-height: 120px;
|
|
168
|
+
max-height: 400px;
|
|
169
|
+
padding: 8px;
|
|
170
|
+
border: none;
|
|
171
|
+
font-family: "Fira Code", "Consolas", monospace;
|
|
172
|
+
font-size: 13px;
|
|
173
|
+
line-height: 1.5;
|
|
174
|
+
resize: vertical;
|
|
175
|
+
box-sizing: border-box;
|
|
176
|
+
outline: none;
|
|
177
|
+
tab-size: 4;
|
|
178
|
+
}
|
|
179
|
+
.pseudocode-area textarea:focus {
|
|
180
|
+
box-shadow: inset 0 0 0 2px rgba(1, 116, 96, 0.3);
|
|
181
|
+
}
|
|
182
|
+
.pseudocode-area .error {
|
|
183
|
+
color: var(--danger);
|
|
184
|
+
font-size: 12px;
|
|
185
|
+
padding: 2px 8px;
|
|
186
|
+
}
|
|
187
|
+
`;class Vt extends HTMLElement{static get observedAttributes(){return["scale","font-size","src","lang","color-mode"]}constructor(){super(),this._tree=null,this._keywords=null,this._mode=null,this._syncing=!1,this._debounceTimer=null,this._shadow=this.attachShadow({mode:"open"});const t=document.createElement("style");t.textContent=me,this._shadow.appendChild(t),this._toolbar=document.createElement("div"),this._toolbar.className="toolbar",this._buildToolbar(),this._shadow.appendChild(this._toolbar),this._editorArea=document.createElement("div"),this._editorArea.className="editor-area",this._shadow.appendChild(this._editorArea),this._pseudoArea=document.createElement("div"),this._pseudoArea.className="pseudocode-area",this._textarea=document.createElement("textarea"),this._textarea.spellcheck=!1,this._textarea.placeholder="Pseudocode...",this._pseudoArea.appendChild(this._textarea),this._errorEl=document.createElement("div"),this._errorEl.className="error",this._errorEl.style.display="none",this._pseudoArea.appendChild(this._errorEl),this._shadow.appendChild(this._pseudoArea),this._overlay=document.createElement("div"),this._overlay.className="text-overlay",this._overlay.style.display="none",this._editorArea.appendChild(this._overlay),this._textarea.addEventListener("input",()=>this._onPseudocodeInput()),this._textarea.addEventListener("blur",()=>this._syncPseudocodeToTree()),this._textarea.addEventListener("keydown",e=>{if(e.key==="Tab"){e.preventDefault();const s=this._textarea,r=s.selectionStart,l=s.selectionEnd;if(e.shiftKey){const n=s.value.substring(0,r).lastIndexOf(`
|
|
188
|
+
`)+1,u=s.value.substring(n);u.startsWith(" ")?(s.value=s.value.substring(0,n)+s.value.substring(n+4),s.selectionStart=s.selectionEnd=Math.max(n,r-4)):u.startsWith(" ")&&(s.value=s.value.substring(0,n)+s.value.substring(n+1),s.selectionStart=s.selectionEnd=Math.max(n,r-1))}else s.value=s.value.substring(0,r)+" "+s.value.substring(l),s.selectionStart=s.selectionEnd=r+4;s.dispatchEvent(new Event("input"))}})}connectedCallback(){requestAnimationFrame(()=>this._initialize())}_getKeywords(){return this._keywords?this._keywords:(this.getAttribute("lang")||"de").toLowerCase()==="en"?Pt:gt}_prepTree(t){return Kt(de(t))}_initialize(){if(!this._tree){const t=this.querySelector('script[type="text/pseudocode"]');if(t)try{this._tree=this._prepTree(Nt(t.textContent,this._getKeywords())),this._emitChange()}catch(e){console.error("struktolab-editor: failed to parse pseudocode",e)}}if(!this._tree){const t=this.querySelector('script[type="application/json"]');if(t)try{this._tree=this._prepTree(JSON.parse(t.textContent)),this._emitChange()}catch(e){console.error("struktolab-editor: invalid inline JSON",e)}}if(!this._tree&&this.hasAttribute("src")){this._fetchTree(this.getAttribute("src"));return}this._tree||(this._tree=Kt({id:"__root",type:"InsertNode",followElement:{type:"Placeholder"}})),this._render(),this._syncTreeToPseudocode()}attributeChangedCallback(t,e,s){t==="src"&&s&&s!==e?this._fetchTree(s):(t==="lang"&&this._langSelect&&(this._langSelect.value=s||"de"),t==="font-size"&&this._fsInput&&(this._fsInput.value=s||"14"),t==="scale"&&this._scaleInput&&(this._scaleInput.value=s||"1"),t==="color-mode"&&this._colorModeSelect&&(this._colorModeSelect.value=s||"color"),this._render())}set tree(t){this._tree=this._prepTree(t),this._render(),this._syncTreeToPseudocode()}get tree(){return this._tree}set keywords(t){this._keywords=t}get keywords(){return this._getKeywords()}set pseudocode(t){this._tree=this._prepTree(Nt(t,this._getKeywords())),this._render(),this._syncTreeToPseudocode()}toCode(t){return this._tree?jt(this._tree,t):""}async _fetchTree(t){try{const e=await fetch(t);this._tree=this._prepTree(await e.json()),this._render(),this._syncTreeToPseudocode()}catch(e){console.error("struktolab-editor: failed to fetch tree from",t,e)}}_buildToolbar(){for(const _ of fe){const g=document.createElement("button");g.textContent=_.icon+" "+_.label,g.dataset.type=_.type,g.title=`Insert ${_.label}`,g.draggable=!0,g.addEventListener("click",()=>this._toggleInsertMode(_.type)),g.addEventListener("dragstart",C=>{C.dataTransfer.setData("text/plain",_.type),C.dataTransfer.effectAllowed="copy",this._setMode("insert:"+_.type)}),g.addEventListener("dragend",()=>{this._mode&&this._mode.startsWith("insert:")&&this._setMode(null)}),this._toolbar.appendChild(g)}const t=document.createElement("span");t.className="sep",this._toolbar.appendChild(t);const e=document.createElement("button");e.textContent="🗑 Delete",e.className="danger",e.title="Delete mode — click a node to remove it",e.addEventListener("click",()=>this._toggleDeleteMode()),this._toolbar.appendChild(e),this._deleteBtn=e;const s=document.createElement("span");s.className="sep",this._toolbar.appendChild(s);const r=document.createElement("label");r.textContent="Lang ";const l=document.createElement("select");l.innerHTML='<option value="de">Deutsch</option><option value="en">English</option>',l.value=(this.getAttribute("lang")||"de").toLowerCase(),l.addEventListener("change",()=>{this.setAttribute("lang",l.value),this._keywords=null,this._onTreeChange()}),r.appendChild(l),this._toolbar.appendChild(r),this._langSelect=l;const i=document.createElement("label");i.textContent="Size ";const n=document.createElement("input");n.type="number",n.min="8",n.max="32",n.value=this.getAttribute("font-size")||"14",n.addEventListener("change",()=>{this.setAttribute("font-size",n.value),this._onTreeChange()}),i.appendChild(n),this._toolbar.appendChild(i),this._fsInput=n;const u=document.createElement("label");u.textContent="Scale ";const c=document.createElement("input");c.type="number",c.min="0.25",c.max="3",c.step="0.25",c.value=this.getAttribute("scale")||"1",c.addEventListener("change",()=>{const _=parseFloat(c.value);_>0?this.setAttribute("scale",String(_)):c.value=this.getAttribute("scale")||"1",this._onTreeChange()}),u.appendChild(c),this._toolbar.appendChild(u),this._scaleInput=c;const a=document.createElement("label");a.textContent="Color Mode ";const m=document.createElement("select");m.innerHTML='<option value="color">Color</option><option value="greyscale">Greyscale</option><option value="bw">Black & White</option>',m.value=this.getAttribute("color-mode")||"color",m.addEventListener("change",()=>{this.setAttribute("color-mode",m.value),this._onTreeChange()}),a.appendChild(m),this._toolbar.appendChild(a),this._colorModeSelect=m;const d=document.createElement("span");d.className="sep",this._toolbar.appendChild(d);const p=document.createElement("button");p.textContent="💾 Save",p.title="Save structogram as JSON",p.addEventListener("click",()=>this._downloadJSON()),this._toolbar.appendChild(p);const h=document.createElement("button");h.textContent="📂 Load",h.title="Load structogram from JSON file",h.addEventListener("click",()=>this._triggerLoadJSON()),this._toolbar.appendChild(h),this._fileInput=document.createElement("input"),this._fileInput.type="file",this._fileInput.accept=".json,application/json",this._fileInput.style.display="none",this._fileInput.addEventListener("change",_=>this._handleFileLoad(_)),this._toolbar.appendChild(this._fileInput);const f=document.createElement("button");f.textContent="🖼 PNG",f.title="Export as PNG image",f.addEventListener("click",()=>this._downloadImage("png")),this._toolbar.appendChild(f);const b=document.createElement("button");b.textContent="📐 SVG",b.title="Export as SVG image",b.addEventListener("click",()=>this._downloadImage("svg")),this._toolbar.appendChild(b)}_toggleInsertMode(t){const e="insert:"+t;this._setMode(this._mode===e?null:e)}_toggleDeleteMode(){this._setMode(this._mode==="delete"?null:"delete")}_setMode(t){this._mode=t;for(const e of this._toolbar.querySelectorAll("button[data-type]"))e.classList.toggle("active",t==="insert:"+e.dataset.type);this._deleteBtn.classList.toggle("active",t==="delete"),this._editorArea.classList.remove("mode-insert","mode-delete"),t&&t.startsWith("insert:")?this._editorArea.classList.add("mode-insert"):t==="delete"&&this._editorArea.classList.add("mode-delete"),this._render()}_resolveWidth(){const t=parseFloat(this.getAttribute("scale"))||1,e=this._editorArea.clientWidth||this.clientWidth||this.getBoundingClientRect().width||600;return Math.round(e/t)}_render(){if(!this._tree)return;const t=parseInt(this.getAttribute("font-size"),10)||14,e=this._resolveWidth(),s=this.getAttribute("color-mode"),r=this._editorArea.querySelector("svg");r&&r.remove();const l=this._mode&&this._mode.startsWith("insert:")||this._mode&&this._mode.startsWith("move:");ft(l?qt:0);const i=Tt(this._tree,{width:e,fontSize:t,colorMode:s});ft(0),this._addInteractivity(i,e,t),this._editorArea.insertBefore(i,this._overlay)}_addInteractivity(t,e,s){const r=this._mode&&this._mode.startsWith("insert:"),l=this._mode==="delete",i=this._mode&&this._mode.startsWith("move:");(r||i)&&this._addInsertTargets(t,e,s,i?this._mode.replace("move:",""):null),l&&this._addDeleteTargets(t,e,s),!r&&!l&&!i&&(this._addEditTargets(t,e,s),this._addDragTargets(t,e,s)),i&&t.addEventListener("click",()=>this._setMode(null))}_computeLayout(t,e,s,r,l,i){const n=new Map;return this._layoutNode(t,e,s,r,l,n,i),n}_layoutNode(t,e,s,r,l,i,n){if(!t)return 0;const u=r-16,c=6,a=20,m=40,d=n?qt:0,p=h=>{const f=this._wrapText(h||"",u,l),b=l*1.3;return Math.max(m,f.length*b+c*2)};switch(t.type){case"InsertNode":{t.id&&i.set(t.id,{x:e,y:s,w:r,h:Math.max(d,4),type:"InsertNode"});const h=this._layoutNode(t.followElement,e,s+d,r,l,i,n);return d+h}case"Placeholder":return 0;case"TaskNode":case"InputNode":case"OutputNode":{let h=t.text||"";t.type==="InputNode"&&(h="▶ "+h),t.type==="OutputNode"&&(h="◀ "+h);const f=p(h);t.id&&i.set(t.id,{x:e,y:s,w:r,h:f,type:t.type,text:t.text});const b=this._layoutNode(t.followElement,e,s+f,r,l,i,n);return f+b}case"InsertCase":{const h=p(t.text||"");t.id&&i.set(t.id,{x:e,y:s,w:r,h,type:"InsertCase",text:t.text});const f=this._layoutNode(t.followElement,e,s+h,r,l,i,n);return h+f}case"BranchNode":{const h=p(t.text||""),f=l*1.3+c,b=l*1.3+c,_=h+f+b,g=2,C=t.columnWidths&&t.columnWidths.length===g?t.columnWidths.map(S=>r*S):[r/g,r/g],L=this._layoutNode(t.trueChild,e,s+_,C[0],l,i,n),I=this._layoutNode(t.falseChild,e+C[0],s+_,C[1],l,i,n),N=Math.max(L,I),y=_+N;t.id&&i.set(t.id,{x:e,y:s,w:r,h:y,type:"BranchNode",text:t.text});const J=this._layoutNode(t.followElement,e,s+y,r,l,i,n);return y+J}case"CaseNode":{const h=(t.cases?t.cases.length:0)+(t.defaultOn?1:0),f=t.columnWidths&&t.columnWidths.length===h?t.columnWidths.map(y=>r*y):Array(h).fill(r/h),b=p(t.text||""),_=l*1.3+c,g=b+_;let C=0,L=e;for(let y=0;y<(t.cases||[]).length;y++){const J=this._layoutNode(t.cases[y],L,s+g,f[y],l,i,n);C=Math.max(C,J),L+=f[y]}if(t.defaultOn&&t.defaultNode){const y=this._layoutNode(t.defaultNode,L,s+g,f[h-1],l,i,n);C=Math.max(C,y)}const I=g+C;t.id&&i.set(t.id,{x:e,y:s,w:r,h:I,type:"CaseNode",text:t.text});const N=this._layoutNode(t.followElement,e,s+I,r,l,i,n);return I+N}case"HeadLoopNode":case"CountLoopNode":{const h=p(t.text||""),f=r-a,b=this._layoutNode(t.child,e+a,s+h,f,l,i,n),_=Math.max(b,h*.5),g=h+_;t.id&&i.set(t.id,{x:e,y:s,w:r,h:g,type:t.type,text:t.text});const C=this._layoutNode(t.followElement,e,s+g,r,l,i,n);return g+C}case"FootLoopNode":{const h=r-a,f=p(t.text||""),b=this._layoutNode(t.child,e+a,s,h,l,i,n),g=Math.max(b,f*.5)+f;t.id&&i.set(t.id,{x:e,y:s,w:r,h:g,type:"FootLoopNode",text:t.text});const C=this._layoutNode(t.followElement,e,s+g,r,l,i,n);return g+C}case"FunctionNode":{let h=t.text||"";t.parameters&&t.parameters.length?h+="("+t.parameters.map(N=>N.parName||"").join(", ")+")":h+="()",h+=" {";const f=p(h),b=r-a,_=this._layoutNode(t.child,e+a,s+f,b,l,i,n),g=Math.max(_,f*.5),C=m*.6,L=f+g+C;t.id&&i.set(t.id,{x:e,y:s,w:r,h:L,type:"FunctionNode",text:t.text});const I=this._layoutNode(t.followElement,e,s+L,r,l,i,n);return L+I}case"TryCatchNode":{const h=r-a,f=p("Try"),b=this._layoutNode(t.tryChild,e+a,s+f,h,l,i,n),_=Math.max(b,f*.5);let g="Catch";t.text&&(g+=" ("+t.text+")");const C=p(g),L=s+f+_,I=this._layoutNode(t.catchChild,e+a,L+C,h,l,i,n),N=Math.max(I,C*.5),y=f+_+C+N;t.id&&i.set(t.id,{x:e,y:s,w:r,h:y,type:"TryCatchNode",text:t.text});const J=this._layoutNode(t.followElement,e,s+y,r,l,i,n);return y+J}default:return 0}}_wrapText(t,e,s){if(!t)return[""];const l=document.createElement("canvas").getContext("2d");l.font=`${s}px sans-serif`;const i=t.split(`
|
|
189
|
+
`),n=[];for(const u of i){if(!u||l.measureText(u).width<=e){n.push(u||"");continue}const c=u.split(/\s+/);let a="";for(const m of c){const d=a?a+" "+m:m;l.measureText(d).width<=e?a=d:(a&&n.push(a),a=m)}a&&n.push(a)}return n.length?n:[""]}_annotatePositions(t,e,s,r,l,i){}_addInsertTargets(t,e,s,r){const l=this._computeLayout(this._tree,0,0,e,s,!0),i="http://www.w3.org/2000/svg",n=[...l.entries()].filter(([,u])=>u.type==="InsertNode").sort(([,u],[,c])=>c.w*c.h-u.w*u.h);for(const[u,c]of n){const a=document.createElementNS(i,"rect");a.setAttribute("x",c.x+2),a.setAttribute("y",c.y),a.setAttribute("width",c.w-4),a.setAttribute("height",c.h),a.setAttribute("fill",kt),a.setAttribute("stroke","none"),a.setAttribute("rx","3"),a.style.cursor="pointer",a.style.transition="fill 0.15s",a.addEventListener("mouseenter",()=>a.setAttribute("fill",Xt)),a.addEventListener("mouseleave",()=>a.setAttribute("fill",kt)),a.addEventListener("click",d=>{d.stopPropagation(),r?(this._tree=this._prepTree(he(this._tree,r,u)),this._setMode(null),this._onTreeChange()):this._handleInsert(u)}),a.addEventListener("dragover",d=>{d.preventDefault(),d.dataTransfer.dropEffect="copy",a.setAttribute("fill",Xt)}),a.addEventListener("dragleave",()=>a.setAttribute("fill",kt)),a.addEventListener("drop",d=>{d.preventDefault();const p=d.dataTransfer.getData("text/plain");p&&(this._tree=this._prepTree(Yt(this._tree,u,p)),this._setMode(null),this._onTreeChange())});const m=document.createElementNS(i,"text");m.setAttribute("x",c.x+c.w/2),m.setAttribute("y",c.y+c.h/2),m.setAttribute("text-anchor","middle"),m.setAttribute("dominant-baseline","central"),m.setAttribute("fill","rgba(1, 116, 96, 0.8)"),m.setAttribute("font-size","16"),m.setAttribute("font-weight","bold"),m.setAttribute("pointer-events","none"),m.textContent="+",t.appendChild(a),t.appendChild(m)}}_handleInsert(t){if(!this._mode||!this._mode.startsWith("insert:"))return;const e=this._mode.replace("insert:","");this._tree=this._prepTree(Yt(this._tree,t,e)),this._setMode(null),this._onTreeChange()}_addDeleteTargets(t,e,s){const r=this._computeLayout(this._tree,0,0,e,s,!1),l="http://www.w3.org/2000/svg",i=[...r.entries()].filter(([,n])=>n.type!=="InsertNode"&&n.type!=="Placeholder"&&n.type!=="InsertCase").sort(([,n],[,u])=>u.w*u.h-n.w*n.h);for(const[n,u]of i){const c=document.createElementNS(l,"rect");c.setAttribute("x",u.x),c.setAttribute("y",u.y),c.setAttribute("width",u.w),c.setAttribute("height",u.h),c.setAttribute("fill","transparent"),c.setAttribute("stroke","none"),c.style.cursor="pointer",c.style.transition="fill 0.15s",c.addEventListener("mouseenter",()=>c.setAttribute("fill",pe)),c.addEventListener("mouseleave",()=>c.setAttribute("fill","transparent")),c.addEventListener("click",a=>{a.stopPropagation(),this._tree=this._prepTree(ie(this._tree,n)),this._setMode(null),this._onTreeChange()}),t.appendChild(c)}}_addEditTargets(t,e,s){const r=this._computeLayout(this._tree,0,0,e,s,!1),l="http://www.w3.org/2000/svg",i=[...r.entries()].filter(([,n])=>n.type!=="InsertNode"&&n.type!=="Placeholder").sort(([,n],[,u])=>u.w*u.h-n.w*n.h);for(const[n,u]of i){const c=document.createElementNS(l,"rect");c.setAttribute("x",u.x),c.setAttribute("y",u.y),c.setAttribute("width",u.w),c.setAttribute("height",u.h),c.setAttribute("fill","transparent"),c.setAttribute("stroke","none"),c.style.cursor="pointer",c.addEventListener("dblclick",a=>{a.stopPropagation(),this._showEditOverlay(n,u)}),t.appendChild(c)}}_showEditOverlay(t,e){const s=ct(this._tree,t);if(!s)return;this._hideEditOverlay();const r=this._editorArea.querySelector("svg");if(!r)return;const l=r.getBoundingClientRect(),i=this._editorArea.getBoundingClientRect(),n=r.viewBox.baseVal,u=l.width/n.width,c=l.height/n.height,a=Math.min(u,c),m=parseInt(this.getAttribute("font-size"),10)||14,d=this._nodeTextHeight(s,e.w,m),p=(e.x-n.x)*a+l.left-i.left,h=(e.y-n.y)*a+l.top-i.top,f=e.w*a,b=d*a;this._overlay.style.display="flex",this._overlay.style.left=p+"px",this._overlay.style.top=h+"px",this._overlay.style.width=f+"px",this._overlay.style.height=b+"px",this._overlay.innerHTML="";const _=document.createElement("textarea");_.value=s.text||"",_.rows=Math.max(2,(s.text||"").split(`
|
|
190
|
+
`).length),_.style.height="100%",_.style.resize="none";const g=document.createElement("button");g.className="ok",g.textContent="✓";const C=document.createElement("button");C.className="cancel",C.textContent="✗";const L=()=>{this._tree=this._prepTree(ue(this._tree,t,_.value)),this._hideEditOverlay(),this._onTreeChange()},I=()=>this._hideEditOverlay();_.addEventListener("keydown",N=>{N.key==="Enter"&&!N.shiftKey&&(N.preventDefault(),L()),N.key==="Escape"&&(N.preventDefault(),I())}),g.addEventListener("click",L),C.addEventListener("click",I),this._overlay.appendChild(_),this._overlay.appendChild(g),this._overlay.appendChild(C),requestAnimationFrame(()=>{_.focus(),_.select()})}_hideEditOverlay(){this._overlay.style.display="none",this._overlay.innerHTML=""}_nodeTextHeight(t,e,s){const r=e-16,l=6,i=40,n=u=>{const c=this._wrapText(u||"",r,s),a=s*1.3;return Math.max(i,c.length*a+l*2)};switch(t.type){case"BranchNode":return n(t.text||"");case"CaseNode":return n(t.text||"");case"HeadLoopNode":case"CountLoopNode":return n(t.text||"");case"FootLoopNode":return n(t.text||"");case"FunctionNode":{let u=t.text||"";return t.parameters&&t.parameters.length?u+="("+t.parameters.map(c=>c.parName||"").join(", ")+")":u+="()",n(u)}case"TryCatchNode":return n(t.text||"");default:return n(t.text||"")}}_addDragTargets(t,e,s){const r=this._computeLayout(this._tree,0,0,e,s,!1),l="http://www.w3.org/2000/svg";for(const[i,n]of r){if(n.type==="InsertNode"||n.type==="Placeholder"||n.type==="InsertCase")continue;const u=14,c=n.x+n.w-u-4,a=n.y+4,m=document.createElementNS(l,"text");m.setAttribute("x",c+u/2),m.setAttribute("y",a+u/2),m.setAttribute("text-anchor","middle"),m.setAttribute("dominant-baseline","central"),m.setAttribute("font-size","12"),m.setAttribute("fill","rgba(0,0,0,0.3)"),m.textContent="⠿",m.style.cursor="grab",m.style.userSelect="none";const d=document.createElementNS(l,"rect");d.setAttribute("x",c),d.setAttribute("y",a),d.setAttribute("width",u),d.setAttribute("height",u),d.setAttribute("fill","transparent"),d.style.cursor="grab";const p=document.createElementNS(l,"g");p.appendChild(d),p.appendChild(m);const h=document.createElementNS(l,"rect");h.setAttribute("x",n.x),h.setAttribute("y",n.y),h.setAttribute("width",n.w),h.setAttribute("height",n.h),h.setAttribute("fill","transparent"),h.setAttribute("stroke","none"),p.addEventListener("mousedown",f=>{f.stopPropagation(),this._startDrag(i)}),t.appendChild(p)}}_startDrag(t){this._setMode("move:"+t)}_syncTreeToPseudocode(){if(!this._syncing){this._syncing=!0;try{const t=Gt(this._tree,this._getKeywords());this._textarea.value=t,this._errorEl.style.display="none"}catch{}this._syncing=!1}}_onPseudocodeInput(){clearTimeout(this._debounceTimer),this._debounceTimer=setTimeout(()=>this._syncPseudocodeToTree(),600)}_syncPseudocodeToTree(){if(!this._syncing){this._syncing=!0,clearTimeout(this._debounceTimer);try{const t=this._textarea.value;if(!t.trim()){this._syncing=!1;return}const e=this._prepTree(Nt(t,this._getKeywords()));this._tree=e,this._errorEl.style.display="none",this._render(),this._emitChange()}catch(t){this._errorEl.textContent="Parse error: "+t.message,this._errorEl.style.display="block"}this._syncing=!1}}_onTreeChange(){this._render(),this._syncTreeToPseudocode(),this._emitChange()}_emitChange(){this.dispatchEvent(new CustomEvent("change",{detail:{tree:ot(this._tree)},bubbles:!0}))}saveJSON(){return this._tree?JSON.stringify(Ut(this._tree),null,2):"{}"}loadJSON(t){const e=typeof t=="string"?JSON.parse(t):t;this._tree=this._prepTree(e),this._render(),this._syncTreeToPseudocode(),this._emitChange()}async exportImage(t="png"){const e=parseInt(this.getAttribute("font-size"),10)||14,s=this._resolveWidth(),r=this.getAttribute("color-mode");ft(0);const l=Tt(this._tree,{width:s,fontSize:e,colorMode:r});ft(0);const n=new XMLSerializer().serializeToString(l);return t==="svg"?new Blob([n],{type:"image/svg+xml"}):new Promise((u,c)=>{const a=new Image,m=new Blob([n],{type:"image/svg+xml"}),d=URL.createObjectURL(m);a.onload=()=>{const p=document.createElement("canvas"),h=8;p.width=a.width*h,p.height=a.height*h;const f=p.getContext("2d");f.fillStyle="#fff",f.fillRect(0,0,a.width,a.height),f.drawImage(a,0,0,p.width,p.height),URL.revokeObjectURL(d),p.toBlob(b=>b?u(b):c(new Error("canvas.toBlob failed")),"image/png")},a.onerror=()=>{URL.revokeObjectURL(d),c(new Error("SVG load failed"))},a.src=d})}change(t){this._tree=this._prepTree(t),this._render(),this._syncTreeToPseudocode(),this._emitChange()}_downloadJSON(){const t=this.saveJSON(),e=new Blob([t],{type:"application/json"});this._downloadBlob(e,"structogram.json")}_triggerLoadJSON(){this._fileInput.value="",this._fileInput.click()}_handleFileLoad(t){const e=t.target.files&&t.target.files[0];if(!e)return;const s=new FileReader;s.onload=()=>{try{this.loadJSON(s.result)}catch(r){console.error("struktolab-editor: invalid JSON file",r)}},s.readAsText(e)}async _downloadImage(t){try{const e=await this.exportImage(t),s=t==="svg"?"svg":"png";this._downloadBlob(e,`structogram.${s}`)}catch(e){console.error("struktolab-editor: export failed",e)}}_downloadBlob(t,e){const s=URL.createObjectURL(t),r=document.createElement("a");r.href=s,r.download=e,r.style.display="none",document.body.appendChild(r),r.click(),setTimeout(()=>{document.body.removeChild(r),URL.revokeObjectURL(s)},100)}}customElements.get("struktolab-editor")||customElements.define("struktolab-editor",Vt),Y.KEYWORDS_DE=gt,Y.KEYWORDS_EN=Pt,Y.StruktolabEditor=Vt,Y.generateCode=jt,Y.parsePseudocode=Nt,Y.renderStructogramSVG=Tt,Y.stripInsertNodes=Ut,Y.treeToPseudocode=Gt,Object.defineProperty(Y,Symbol.toStringTag,{value:"Module"})}));
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
(function(J,st){typeof exports=="object"&&typeof module<"u"?st(exports):typeof define=="function"&&define.amd?define(["exports"],st):(J=typeof globalThis<"u"?globalThis:J||self,st(J.StruktolabRenderer={}))})(this,(function(J){"use strict";const st="http://www.w3.org/2000/svg",bt={color:s=>({TaskNode:"rgb(253, 237, 206)",InputNode:"rgb(253, 237, 206)",OutputNode:"rgb(253, 237, 206)",HeadLoopNode:"rgb(220, 239, 231)",CountLoopNode:"rgb(220, 239, 231)",FootLoopNode:"rgb(220, 239, 231)",BranchNode:"rgb(250, 218, 209)",CaseNode:"rgb(250, 218, 209)",InsertCase:"rgb(250, 218, 209)",TryCatchNode:"rgb(250, 218, 209)",FunctionNode:"rgb(255, 255, 255)"})[s],bw:s=>({TaskNode:"rgb(255, 255, 255)",InputNode:"rgb(255, 255, 255)",OutputNode:"rgb(255, 255, 255)",HeadLoopNode:"rgb(255, 255, 255)",CountLoopNode:"rgb(255, 255, 255)",FootLoopNode:"rgb(255, 255, 255)",BranchNode:"rgb(255, 255, 255)",CaseNode:"rgb(255, 255, 255)",InsertCase:"rgb(255, 255, 255)",TryCatchNode:"rgb(255, 255, 255)",FunctionNode:"rgb(255, 255, 255)"})[s]||"rgb(255, 255, 255)",greyscale:s=>({TaskNode:"rgb(250, 250, 250)",InputNode:"rgb(250, 250, 250)",OutputNode:"rgb(250, 250, 250)",HeadLoopNode:"rgb(245, 245, 245)",CountLoopNode:"rgb(245, 245, 245)",FootLoopNode:"rgb(245, 245, 245)",BranchNode:"rgb(240, 240, 240)",CaseNode:"rgb(240, 240, 240)",InsertCase:"rgb(240, 240, 240)",TryCatchNode:"rgb(240, 240, 240)",FunctionNode:"rgb(255, 255, 255)"})[s]};let wt="color";function S(s){return bt[wt](s)}const pt=40,g=20,K=8,et=6,Pt="#333",kt=1.5;let Et=0,it=null;function xt(s){it||(it=document.createElement("canvas"));const e=it.getContext("2d");return e.font=`${s}px sans-serif`,e}function Ht(s,e,t){if(!s)return[""];const c=xt(t),o=s.split(`
|
|
2
|
+
`),r=[];for(const h of o){if(!h||c.measureText(h).width<=e){r.push(h||"");continue}const n=h.split(/\s+/);let a="";for(const l of n){const u=a?a+" "+l:l;c.measureText(u).width>e&&a?(r.push(a),a=l):a=u}a&&r.push(a)}return r.length?r:[""]}function B(s,e,t){const c=Ht(s,e,t),o=t*1.3;return Math.max(pt,c.length*o+et*2)}function ot(s,e={}){const t=document.createElementNS(st,s);for(const[c,o]of Object.entries(e))t.setAttribute(c,String(o));return t}function Y(s,e,t,c,o,r,h="start"){const n=r!=null?Ht(s,r,o):[s||""],a=o*1.3,l=n.length*a,u=t+(c-l)/2+a/2,b=ot("text",{x:e,"font-size":o,"font-family":"sans-serif",fill:"#333","text-anchor":h,"dominant-baseline":"central"});for(let p=0;p<n.length;p++){const i=ot("tspan",{x:e,dy:p===0?0:a});p===0&&i.setAttribute("y",u),i.textContent=n[p],b.appendChild(i)}return b}function F(s,e,t,c,o){return ot("rect",{x:s,y:e,width:t,height:c,fill:o,stroke:"none"})}function f(s,e,t,c){return ot("line",{x1:s,y1:e,x2:t,y2:c,stroke:Pt,"stroke-width":kt})}function rt(s,e,t){if(t&&t.length===e)return t.map(o=>s*o);const c=s/e;return Array(e).fill(c)}function C(s,e,t){if(!s)return 0;const c=t-K*2;switch(s.type){case"InsertNode":return Et+C(s.followElement,e,t);case"Placeholder":return 0;case"TaskNode":case"InputNode":case"OutputNode":{let o=s.text||"";return s.type==="InputNode"&&(o="▶ "+o),s.type==="OutputNode"&&(o="◀ "+o),B(o,c,e)+C(s.followElement,e,t)}case"InsertCase":return B(s.text||"",c,e)+C(s.followElement,e,t);case"BranchNode":{const o=B(s.text||"",c,e),r=e*1.3+et,h=e*1.3+et,n=o+r+h,a=rt(t,2,s.columnWidths),l=C(s.trueChild,e,a[0]),u=C(s.falseChild,e,a[1]);return n+Math.max(l,u)+C(s.followElement,e,t)}case"CaseNode":{const o=s.cases.length+(s.defaultOn?1:0),r=rt(t,o,s.columnWidths),h=B(s.text||"",c,e),n=e*1.3+et,a=h+n;let l=0;for(let u=0;u<s.cases.length;u++)l=Math.max(l,C(s.cases[u],e,r[u]));return s.defaultOn&&s.defaultNode&&(l=Math.max(l,C(s.defaultNode,e,r[o-1]))),a+l+C(s.followElement,e,t)}case"HeadLoopNode":case"CountLoopNode":{const o=t-g,r=B(s.text||"",c,e),h=C(s.child,e,o),n=Math.max(h,r*.5);return r+n+C(s.followElement,e,t)}case"FootLoopNode":{const o=t-g,r=B(s.text||"",c,e),h=C(s.child,e,o);return Math.max(h,r*.5)+r+C(s.followElement,e,t)}case"FunctionNode":{const o=t-g;let r=s.text||"";s.parameters&&s.parameters.length>0?r+="("+s.parameters.map(u=>u.parName||"").join(", ")+")":r+="()",r+=" {";const h=B(r,c,e),n=C(s.child,e,o),a=Math.max(n,h*.5),l=pt*.6;return h+a+l+C(s.followElement,e,t)}case"TryCatchNode":{const o=t-g,r=B("Try",c,e);let h="Catch";s.text&&(h+=" ("+s.text+")");const n=B(h,c,e),a=C(s.tryChild,e,o),l=Math.max(a,r*.5),u=C(s.catchChild,e,o),b=Math.max(u,n*.5);return r+l+n+b+C(s.followElement,e,t)}default:return 0}}function _(s,e,t,c,o,r){if(!s)return{elements:[],height:0};const h=c-K*2,n=[];switch(s.type){case"InsertNode":{const a=Et,l=_(s.followElement,e,t+a,c,o,r?r-a:void 0);return{elements:l.elements,height:a+l.height}}case"Placeholder":return{elements:[],height:0};case"TaskNode":case"InputNode":case"OutputNode":{const a=S(s.type);let l=s.text||"";s.type==="InputNode"&&(l="▶ "+l),s.type==="OutputNode"&&(l="◀ "+l);const u=B(l,h,o),b=C(s.followElement,o,c),p=u+b,i=r!=null&&r>p?u+(r-p):u;n.push(F(e,t,c,i,a)),n.push(f(e,t,e+c,t)),n.push(f(e,t,e,t+i)),n.push(Y(l,e+K,t,u,o,h));const d=r!=null?r-i:void 0,N=_(s.followElement,e,t+i,c,o,d);return{elements:n.concat(N.elements),height:i+N.height}}case"InsertCase":{const a=S(s.type),l=B(s.text||"",h,o),u=C(s.followElement,o,c),b=l+u,p=r!=null&&r>b?l+(r-b):l;n.push(F(e,t,c,p,a)),n.push(f(e,t,e,t+p)),n.push(Y(s.text||"",e+K,t,l,o,h));const i=r!=null?r-p:void 0,d=_(s.followElement,e,t+p,c,o,i);return{elements:n.concat(d.elements),height:p+d.height}}case"BranchNode":{const a=S(s.type),l=B(s.text||"",h,o),u=o*1.3+et,b=o*1.3+et,p=l+u+b,i=rt(c,2,s.columnWidths),d=e+i[0];n.push(F(e,t,c,p,a)),n.push(f(e,t,e+c,t)),n.push(f(e,t,e,t+p)),n.push(Y(s.text||"",e+c/2,t,l,o,h,"middle"));const N=t+l+u;n.push(f(e,t+l,d,N)),n.push(f(e+c,t+l,d,N));const w=o*.8;n.push(Y("Wahr",e+K,N,b,w,null)),n.push(Y("Falsch",e+c-K,N,b,w,null,"end")),n.push(f(d,N,d,t+p));const U=C(s.trueChild,o,i[0]),E=C(s.falseChild,o,i[1]),A=C(s.followElement,o,c),j=Math.max(U,E),Q=r!=null&&r>p+j+A?r-p-j-A:0,m=j+Q,D=_(s.trueChild,e,t+p,i[0],o,m);n.push(...D.elements);const v=_(s.falseChild,d,t+p,i[1],o,m);n.push(...v.elements),n.push(f(d,t+p,d,t+p+m));const y=p+m,nt=r!=null?r-y:void 0,at=_(s.followElement,e,t+y,c,o,nt);return{elements:n.concat(at.elements),height:y+at.height}}case"CaseNode":{const a=S(s.type),l=s.cases.length+(s.defaultOn?1:0),u=rt(c,l,s.columnWidths),b=B(s.text||"",h,o),p=o*1.3+et,i=b+p;n.push(F(e,t,c,i,a)),n.push(f(e,t,e+c,t)),n.push(f(e,t,e,t+i)),n.push(Y(s.text||"",e+c/2,t,b,o,h,"middle"));const d=[0];for(let m=0;m<l;m++)d.push(d[m]+u[m]);if(s.defaultOn){const m=e+d[l-1];n.push(f(e,t+b,m,t+i)),n.push(f(e+c,t+b,m,t+i));for(let D=1;D<l-1;D++){const v=e+d[D],y=d[D]/d[l-1],nt=t+b+p*y;n.push(f(v,nt,v,t+i))}}else{n.push(f(e,t+b,e+c,t+i));for(let m=1;m<l;m++){const D=e+d[m],v=d[m]/c,y=t+b+p*v;n.push(f(D,y,D,t+i))}}let N=0;for(let m=0;m<s.cases.length;m++){const D=C(s.cases[m],o,u[m]);N=Math.max(N,D)}if(s.defaultOn&&s.defaultNode){const m=C(s.defaultNode,o,u[l-1]);N=Math.max(N,m)}const w=C(s.followElement,o,c),U=r!=null&&r>i+N+w?r-i-N-w:0;N+=U;let E=e;for(let m=0;m<s.cases.length;m++){const D=_(s.cases[m],E,t+i,u[m],o,N);n.push(...D.elements),m>0&&n.push(f(E,t+i,E,t+i+N)),E+=u[m]}if(s.defaultOn&&s.defaultNode){const m=_(s.defaultNode,E,t+i,u[l-1],o,N);n.push(...m.elements),n.push(f(E,t+i,E,t+i+N))}const A=i+N,j=r!=null?r-A:void 0,Q=_(s.followElement,e,t+A,c,o,j);return{elements:n.concat(Q.elements),height:A+Q.height}}case"HeadLoopNode":case"CountLoopNode":{const a=S(s.type),l=B(s.text||"",h,o);n.push(F(e,t,c,l,a)),n.push(f(e,t,e+c,t)),n.push(f(e,t,e,t+l)),n.push(Y(s.text||"",e+K,t,l,o,h));const u=c-g,b=C(s.child,o,u),p=Math.max(b,l*.5);n.push(F(e,t+l,g,p,a)),n.push(f(e,t+l,e,t+l+p)),n.push(f(e+g,t+l,e+g,t+l+p));const i=_(s.child,e+g,t+l,u,o);n.push(...i.elements);const d=l+p,N=r!=null?r-d:void 0,w=_(s.followElement,e,t+d,c,o,N);return{elements:n.concat(w.elements),height:d+w.height}}case"FootLoopNode":{const a=S(s.type),l=c-g,u=B(s.text||"",h,o),b=C(s.child,o,l),p=Math.max(b,u*.5);n.push(F(e,t,g,p,a)),n.push(f(e,t,e+c,t)),n.push(f(e,t,e,t+p)),n.push(f(e+g,t,e+g,t+p));const i=_(s.child,e+g,t,l,o);n.push(...i.elements),n.push(F(e,t+p,c,u,a)),n.push(f(e+g,t+p,e+c,t+p)),n.push(f(e,t+p,e,t+p+u)),n.push(Y(s.text||"",e+K,t+p,u,o,h));const d=p+u,N=r!=null?r-d:void 0,w=_(s.followElement,e,t+d,c,o,N);return{elements:n.concat(w.elements),height:d+w.height}}case"FunctionNode":{const a=S(s.type);let l=s.text||"";if(s.parameters&&s.parameters.length>0){const A=s.parameters.map(j=>j.parName||"").join(", ");l+="("+A+")"}else l+="()";l+=" {";const u=B(l,h,o);n.push(F(e,t,c,u,a)),n.push(f(e,t,e+c,t)),n.push(f(e,t,e,t+u)),n.push(Y(l,e+K,t,u,o,h));const b=c-g,p=C(s.child,o,b),i=Math.max(p,u*.5);n.push(F(e,t+u,g,i,a)),n.push(f(e,t+u,e,t+u+i)),n.push(f(e+g,t+u,e+g,t+u+i));const d=_(s.child,e+g,t+u,b,o);n.push(...d.elements);const N=pt*.6;n.push(F(e,t+u+i,c,N,a)),n.push(f(e+g,t+u+i,e+c,t+u+i)),n.push(f(e,t+u+i,e,t+u+i+N)),n.push(Y("}",e+K,t+u+i,N,o,null));const w=u+i+N,U=r!=null?r-w:void 0,E=_(s.followElement,e,t+w,c,o,U);return{elements:n.concat(E.elements),height:w+E.height}}case"TryCatchNode":{const a=S(s.type),l=c-g,u=B("Try",h,o);n.push(F(e,t,c,u,a)),n.push(f(e,t,e+c,t)),n.push(f(e,t,e,t+u)),n.push(Y("Try",e+K,t,u,o,null));const b=C(s.tryChild,o,l),p=Math.max(b,u*.5);n.push(F(e,t+u,g,p,a)),n.push(f(e,t+u,e,t+u+p)),n.push(f(e+g,t+u,e+g,t+u+p));const i=_(s.tryChild,e+g,t+u,l,o);n.push(...i.elements);const d=t+u+p;let N="Catch";s.text&&(N+=" ("+s.text+")");const w=B(N,h,o);n.push(F(e,d,c,w,a)),n.push(f(e+g,d,e+c,d)),n.push(f(e,d,e,d+w)),n.push(Y(N,e+K,d,w,o,h));const U=C(s.catchChild,o,l),E=Math.max(U,w*.5);n.push(F(e,d+w,g,E,a)),n.push(f(e,d+w,e,d+w+E)),n.push(f(e+g,d+w,e+g,d+w+E)),n.push(f(e,d+w+E,e+g,d+w+E));const A=_(s.catchChild,e+g,d+w,l,o);n.push(...A.elements);const j=u+p+w+E,Q=r!=null?r-j:void 0,m=_(s.followElement,e,t+j,c,o,Q);return{elements:n.concat(m.elements),height:j+m.height}}default:return{elements:[],height:0}}}function _t(s,e={}){const t=e.width||600,c=e.fontSize||14;e.colorMode&&bt[e.colorMode]&&(wt=e.colorMode);const r=C(s,c,t)||40,h=kt,n=ot("svg",{xmlns:st,viewBox:`${-h} ${-h} ${t+h*2} ${r+h*2}`,preserveAspectRatio:"xMinYMin meet"});n.style.display="block",n.style.width="100%",n.style.height="auto";const a=_(s,0,0,t,c);for(const l of a.elements)n.appendChild(l);return n.appendChild(f(t,0,t,a.height)),n.appendChild(f(0,a.height,t,a.height)),n}const dt={if:"falls",else:"sonst",repeat:"wiederhole",while:"solange",for:"für",switch:"unterscheide",case:"fall",function:"funktion",try:"versuche",catch:"fange",input:"eingabe",output:"ausgabe",true:"Wahr",false:"Falsch",default:"Sonst"},Bt={if:"if",else:"else",repeat:"repeat",while:"while",for:"for",switch:"switch",case:"case",function:"function",try:"try",catch:"catch",input:"input",output:"output",true:"True",false:"False",default:"Default"};function X(s){return s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}let Tt=0;function $(){return"__pseudo_"+ ++Tt}function L(s){return{id:$(),type:"InsertNode",followElement:s}}function lt(){return{type:"Placeholder"}}function ft(s){const e=s.match(/^(.*?)\s*\[([0-9.,\s]+)\]\s*$/);if(e){const t=e[1].trim(),c=e[2].split(",").map(o=>parseFloat(o.trim())).filter(o=>!isNaN(o));return{text:t,columnWidths:c.length>0?c:null}}return{text:s,columnWidths:null}}function Kt(s){const e=s.split(`
|
|
3
|
+
`),t=[];for(const c of e){const o=c.trimEnd();if(o===""||o.startsWith("#"))continue;const r=c.replace(/\t/g," "),h=r.length-r.trimStart().length;t.push({text:o.trim(),indent:h})}return t}function Lt(s,e){const t=[];let c=0;for(;c<s.length;){const o=s[c];if(o.indent<e)break;if(o.indent>e){c++;continue}const r=[];for(c++;c<s.length&&s[c].indent>e;)r.push(s[c]),c++;t.push({text:o.text,indent:o.indent,children:r})}return t}function mt(s){return s.endsWith(":")?s.slice(0,-1).trimEnd():s}function G(s,e,t){const c=Lt(s,e);if(c.length===0)return L(lt());const o=X(t.try),r=X(t.catch),h=X(t.if),n=X(t.else),a=X(t.repeat),l=X(t.while),u=X(t.for),b=X(t.switch),p=X(t.case),i=X(t.function),d=X(t.input),N=X(t.output),w=new RegExp(`^${o}\\s*:$`,"i"),U=new RegExp(`^${r}\\s+`,"i"),E=new RegExp(`^${h}\\s+`,"i"),A=new RegExp(`^${n}\\s*:$`,"i"),j=new RegExp(`^${a}\\s*:$`,"i"),Q=new RegExp(`^${l}\\s+`,"i"),m=new RegExp(`^${a}\\s+${u}\\s+(.+)\\s*:$`,"i"),D=new RegExp(`^${a}\\s+${l}\\s+(.+)\\s*:$`,"i"),v=new RegExp(`^${i}\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*:$`,"i"),y=new RegExp(`^${b}\\s+(.+)\\s*:$`,"i"),nt=new RegExp(`^${p}\\s+(.+)\\s*:$`,"i"),at=new RegExp(`^${d}\\s*\\(\\s*"?([^"]*)"?\\s*\\)$`,"i"),Yt=new RegExp(`^${N}\\s*\\(\\s*"?([^"]*)"?\\s*\\)$`,"i"),q=[];for(const I of c)q.push({block:I,_skip:!1});for(let I=0;I<q.length-1;I++){const P=q[I].block.text,T=q[I+1].block.text;(w.test(P)&&U.test(T)||E.test(P)&&A.test(T)||j.test(P)&&Q.test(T)&&!T.endsWith(":"))&&(q[I+1]._skip=!0)}let H=L(null);for(let I=q.length-1;I>=0;I--){const P=q[I].block,T=P.text;if(q[I]._skip)continue;const V=I+1<q.length?q[I+1].block:null;if(w.test(T)&&V&&U.test(V.text)){const O=e+4,R=G(P.children,O,t),W=mt(V.text.replace(U,"")),x=G(V.children,O,t);H=L({id:$(),type:"TryCatchNode",text:W,tryChild:R,catchChild:x,followElement:H});continue}if(E.test(T)&&V&&A.test(V.text)){const O=mt(T.replace(E,"")),{text:R,columnWidths:W}=ft(O),x=e+4,z=G(P.children,x,t),tt=G(V.children,x,t),Z={id:$(),type:"BranchNode",text:R,trueChild:z,falseChild:tt,followElement:H};W&&(Z.columnWidths=W),H=L(Z);continue}if(E.test(T)){const O=mt(T.replace(E,"")),{text:R,columnWidths:W}=ft(O),x=e+4,z=G(P.children,x,t),tt={id:$(),type:"BranchNode",text:R,trueChild:z,falseChild:L(lt()),followElement:H};W&&(tt.columnWidths=W),H=L(tt);continue}if(j.test(T)&&V&&Q.test(V.text)&&!V.text.endsWith(":")){const O=V.text.replace(Q,"").trim(),R=e+4,W=G(P.children,R,t);H=L({id:$(),type:"FootLoopNode",text:O,child:W,followElement:H});continue}const Wt=T.match(m);if(Wt){const O=e+4,R=G(P.children,O,t);H=L({id:$(),type:"CountLoopNode",text:Wt[1],child:R,followElement:H});continue}const Ft=T.match(D);if(Ft){const O=e+4,R=G(P.children,O,t);H=L({id:$(),type:"HeadLoopNode",text:Ft[1],child:R,followElement:H});continue}const Nt=T.match(v);if(Nt){const O=Nt[1],R=Nt[2].trim(),W=R?R.split(",").map((Z,ct)=>({pos:String(ct*3),parName:Z.trim()})):[],x=e+4,z=G(P.children,x,t);H=L({id:$(),type:"FunctionNode",text:O,parameters:W,child:z,followElement:H});continue}const $t=T.match(y);if($t){const O=$t[1],{text:R,columnWidths:W}=ft(O),x=e+4,z=Lt(P.children,x),tt=[];let Z=null,ct=!1;for(const ht of z){const jt=ht.text.match(nt);if(jt){const gt=x+4,Ct=G(ht.children,gt,t);tt.push({id:$(),type:"InsertCase",text:jt[1].replace(/^"(.*)"$/,"$1"),followElement:Ct})}else if(A.test(ht.text)){ct=!0;const gt=x+4,Ct=G(ht.children,gt,t);Z={id:$(),type:"InsertCase",text:t.default,followElement:Ct}}}Z||(Z={id:$(),type:"InsertCase",text:t.default,followElement:L(lt())});const At={id:$(),type:"CaseNode",text:R,defaultOn:ct,defaultNode:Z,cases:tt,followElement:H};W&&(At.columnWidths=W),H=L(At);continue}const Mt=T.match(at);if(Mt){H=L({id:$(),type:"InputNode",text:Mt[1],followElement:H});continue}const Dt=T.match(Yt);if(Dt){H=L({id:$(),type:"OutputNode",text:Dt[1],followElement:H});continue}H=L({id:$(),type:"TaskNode",text:T,followElement:H})}return H}function ut(s,e=dt){Tt=0;const t=Kt(s);if(t.length===0)return L(lt());const c=Math.min(...t.map(o=>o.indent));return G(t,c,e)}const It={python:{InputNode:{pre:"",post:` = input("Eingabe")
|
|
4
|
+
`},OutputNode:{pre:"print(",post:`)
|
|
5
|
+
`},TaskNode:{pre:"",post:`
|
|
6
|
+
`},BranchNode:{pre:"if ",post:`:
|
|
7
|
+
`,between:`else:
|
|
8
|
+
`},TryCatchNode:{pre:`try:
|
|
9
|
+
`,between:"except ",post:`:
|
|
10
|
+
`},CountLoopNode:{pre:"for ",post:`:
|
|
11
|
+
`},HeadLoopNode:{pre:"while ",post:`:
|
|
12
|
+
`},FootLoopNode:{prepre:`while True:
|
|
13
|
+
`,pre:" if not ",post:`:
|
|
14
|
+
break
|
|
15
|
+
`},FunctionNode:{pre:"def ",between:"(",post:`):
|
|
16
|
+
`},CaseNode:{pre:"if ",post:`:
|
|
17
|
+
`},InsertCase:{preNormal:"elif ",preDefault:"else",post:`:
|
|
18
|
+
`,postpost:`
|
|
19
|
+
`},leftBracket:"",rightBracket:"",pseudoSwitch:!0},java:{InputNode:{pre:"",post:` = System.console().readLine();
|
|
20
|
+
`},OutputNode:{pre:"System.out.println(",post:`);
|
|
21
|
+
`},TaskNode:{pre:"",post:`;
|
|
22
|
+
`},BranchNode:{pre:"if (",post:")",between:`} else {
|
|
23
|
+
`},TryCatchNode:{pre:"try",between:"catch (",post:")"},CountLoopNode:{pre:"for (",post:")"},HeadLoopNode:{pre:"while (",post:")"},FootLoopNode:{prepre:"do",pre:"while (",post:`);
|
|
24
|
+
`},FunctionNode:{pre:"public void ",between:"(",post:")"},CaseNode:{pre:"switch (",post:")"},InsertCase:{preNormal:"case ",preDefault:"default",post:`:
|
|
25
|
+
`,postpost:`break;
|
|
26
|
+
`},leftBracket:"{",rightBracket:"}",pseudoSwitch:!1},javascript:{InputNode:{pre:"",post:` = prompt("Eingabe");
|
|
27
|
+
`},OutputNode:{pre:"console.log(",post:`);
|
|
28
|
+
`},TaskNode:{pre:"",post:`;
|
|
29
|
+
`},BranchNode:{pre:"if (",post:")",between:`} else {
|
|
30
|
+
`},TryCatchNode:{pre:"try",between:"catch (",post:")"},CountLoopNode:{pre:"for (",post:")"},HeadLoopNode:{pre:"while (",post:")"},FootLoopNode:{prepre:"do",pre:"while (",post:`);
|
|
31
|
+
`},FunctionNode:{pre:"function ",between:"(",post:")"},CaseNode:{pre:"switch (",post:")"},InsertCase:{preNormal:"case ",preDefault:"default",post:`:
|
|
32
|
+
`,postpost:`break;
|
|
33
|
+
`},leftBracket:"{",rightBracket:"}",pseudoSwitch:!1}};function k(s){return" ".repeat(s)}function Ot(s,e="python"){const t=It[e.toLowerCase()];if(!t)throw new Error(`Unsupported language: ${e}. Supported: ${Object.keys(It).join(", ")}`);return M(s,0,t,e.toLowerCase()).join("")}function M(s,e,t,c){if(!s)return[];if(s.type==="InsertNode"||s.type==="Placeholder")return M(s.followElement,e,t,c);const o=s.text||"",r=[];switch(s.type){case"TaskNode":r.push(k(e)+t.TaskNode.pre+o+t.TaskNode.post);break;case"InputNode":r.push(k(e)+t.InputNode.pre+o+t.InputNode.post);break;case"OutputNode":r.push(k(e)+t.OutputNode.pre+o+t.OutputNode.post);break;case"BranchNode":{r.push(k(e)+t.BranchNode.pre+o+t.BranchNode.post+(t.leftBracket?" "+t.leftBracket+`
|
|
34
|
+
`:"")),r.push(...M(s.trueChild,e+1,t,c)),r.push(k(e)+t.BranchNode.between),r.push(...M(s.falseChild,e+1,t,c)),t.rightBracket&&r.push(k(e)+t.rightBracket+`
|
|
35
|
+
`);break}case"HeadLoopNode":r.push(k(e)+t.HeadLoopNode.pre+o+t.HeadLoopNode.post+(t.leftBracket?" "+t.leftBracket+`
|
|
36
|
+
`:"")),r.push(...M(s.child,e+1,t,c)),t.rightBracket&&r.push(k(e)+t.rightBracket+`
|
|
37
|
+
`);break;case"CountLoopNode":r.push(k(e)+t.CountLoopNode.pre+o+t.CountLoopNode.post+(t.leftBracket?" "+t.leftBracket+`
|
|
38
|
+
`:"")),r.push(...M(s.child,e+1,t,c)),t.rightBracket&&r.push(k(e)+t.rightBracket+`
|
|
39
|
+
`);break;case"FootLoopNode":{r.push(k(e)+t.FootLoopNode.prepre+(t.leftBracket?" "+t.leftBracket+`
|
|
40
|
+
`:"")),r.push(...M(s.child,e+1,t,c)),t.pseudoSwitch?r.push(k(e)+t.FootLoopNode.pre+o+t.FootLoopNode.post):(t.rightBracket&&r.push(k(e)+t.rightBracket+" "),r.push(t.FootLoopNode.pre+o+t.FootLoopNode.post));break}case"FunctionNode":{const h=(s.parameters||[]).map(n=>n.parName).join(", ");r.push(k(e)+t.FunctionNode.pre+o+t.FunctionNode.between+h+t.FunctionNode.post+(t.leftBracket?" "+t.leftBracket+`
|
|
41
|
+
`:"")),r.push(...M(s.child,e+1,t,c)),t.rightBracket&&r.push(k(e)+t.rightBracket+`
|
|
42
|
+
`);break}case"TryCatchNode":{r.push(k(e)+t.TryCatchNode.pre+(t.leftBracket?" "+t.leftBracket+`
|
|
43
|
+
`:"")),r.push(...M(s.tryChild,e+1,t,c)),r.push(k(e)+(t.rightBracket?t.rightBracket+" ":"")+t.TryCatchNode.between+o+t.TryCatchNode.post+(t.leftBracket?" "+t.leftBracket+`
|
|
44
|
+
`:"")),r.push(...M(s.catchChild,e+1,t,c)),t.rightBracket&&r.push(k(e)+t.rightBracket+`
|
|
45
|
+
`);break}case"CaseNode":{if(t.pseudoSwitch){let h=!0;for(const n of s.cases||[])if(n.type==="InsertCase"){const a=h?"if ":t.InsertCase.preNormal;r.push(k(e)+a+o+" == "+n.text+t.InsertCase.post),r.push(...M(n.followElement,e+1,t,c)),h=!1}s.defaultOn&&s.defaultNode&&(r.push(k(e)+t.InsertCase.preDefault+t.InsertCase.post),r.push(...M(s.defaultNode.followElement,e+1,t,c)))}else{r.push(k(e)+t.CaseNode.pre+o+t.CaseNode.post+(t.leftBracket?" "+t.leftBracket+`
|
|
46
|
+
`:""));for(const h of s.cases||[])h.type==="InsertCase"&&(r.push(k(e+1)+t.InsertCase.preNormal+h.text+t.InsertCase.post),r.push(...M(h.followElement,e+2,t,c)),t.InsertCase.postpost&&r.push(k(e+2)+t.InsertCase.postpost));s.defaultOn&&s.defaultNode&&(r.push(k(e+1)+t.InsertCase.preDefault+t.InsertCase.post),r.push(...M(s.defaultNode.followElement,e+2,t,c)),c==="java"&&r.push(k(e+2)+t.InsertCase.postpost)),t.rightBracket&&r.push(k(e)+t.rightBracket+`
|
|
47
|
+
`)}break}}return r.push(...M(s.followElement,e,t,c)),r}class Rt extends HTMLElement{static get observedAttributes(){return["width","font-size","src","lang","scale","color-mode"]}constructor(){super(),this._tree=null,this._keywords=null,this._shadow=this.attachShadow({mode:"open"});const e=document.createElement("style");e.textContent=":host { display: block; width: 100%; }",this._shadow.appendChild(e),this._container=document.createElement("div"),this._shadow.appendChild(this._container)}connectedCallback(){requestAnimationFrame(()=>this._initialize())}_getKeywords(){return this._keywords?this._keywords:(this.getAttribute("lang")||"de").toLowerCase()==="en"?Bt:dt}_initialize(){if(!this._tree){const e=this.querySelector('script[type="text/pseudocode"]');if(e)try{this._tree=ut(e.textContent,this._getKeywords())}catch(t){console.error("struktolab-renderer: failed to parse pseudocode",t)}}if(!this._tree){const e=this.querySelector('script[type="application/json"]');if(e)try{this._tree=JSON.parse(e.textContent)}catch(t){console.error("struktolab-renderer: invalid inline JSON",t)}}if(!this._tree&&this.hasAttribute("src")){this._fetchTree(this.getAttribute("src"));return}this._render()}attributeChangedCallback(e,t,c){if(e==="src"&&c&&c!==t)this._fetchTree(c);else if(e==="lang"){const o=this.querySelector('script[type="text/pseudocode"]');if(o)try{this._tree=ut(o.textContent,this._getKeywords())}catch{}this._render()}else this._render()}set tree(e){this._tree=e,this._render()}get tree(){return this._tree}set keywords(e){this._keywords=e}get keywords(){return this._getKeywords()}set pseudocode(e){this._tree=ut(e,this._getKeywords()),this._render()}toCode(e){return this._tree?Ot(this._tree,e):""}async _fetchTree(e){try{const t=await fetch(e);this._tree=await t.json(),this._render()}catch(t){console.error("struktolab-renderer: failed to fetch tree from",e,t)}}_resolveWidth(){const e=parseFloat(this.getAttribute("scale"))||1,t=this.clientWidth||this.getBoundingClientRect().width||600;return Math.round(t/e)}_render(){if(!this._tree)return;const e=parseInt(this.getAttribute("font-size"),10)||14;this.getAttribute("width"),parseFloat(this.getAttribute("scale"));const t=this.getAttribute("color-mode")||"color",c=this._resolveWidth();for(;this._container.firstChild;)this._container.removeChild(this._container.firstChild);const o=_t(this._tree,{width:c,fontSize:e,colorMode:t});this._container.appendChild(o)}}customElements.get("struktolab-renderer")||customElements.define("struktolab-renderer",Rt),J.KEYWORDS_DE=dt,J.KEYWORDS_EN=Bt,J.StruktolabRenderer=Rt,J.generateCode=Ot,J.parsePseudocode=ut,J.renderStructogramSVG=_t,Object.defineProperty(J,Symbol.toStringTag,{value:"Module"})}));
|
|
File without changes
|
|
@@ -20,7 +20,7 @@ hyperbook.youtube.consent = (function () {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function loadContent(wrapper) {
|
|
23
|
-
var banner = wrapper.querySelector(".directive-youtube
|
|
23
|
+
var banner = wrapper.querySelector(".directive-youtube .consent-banner");
|
|
24
24
|
if (banner) {
|
|
25
25
|
banner.remove();
|
|
26
26
|
}
|
|
@@ -45,9 +45,9 @@ hyperbook.youtube.consent = (function () {
|
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
var btn = wrapper.querySelector(".directive-youtube
|
|
48
|
+
var btn = wrapper.querySelector(".directive-youtube .consent-accept-btn");
|
|
49
49
|
var checkbox = wrapper.querySelector(
|
|
50
|
-
".directive-youtube
|
|
50
|
+
".directive-youtube .consent-always-checkbox"
|
|
51
51
|
);
|
|
52
52
|
if (btn) {
|
|
53
53
|
btn.addEventListener("click", async function () {
|
|
@@ -57,7 +57,7 @@ hyperbook.youtube.consent = (function () {
|
|
|
57
57
|
loadContent(wrapper);
|
|
58
58
|
if (checkbox && checkbox.checked) {
|
|
59
59
|
document
|
|
60
|
-
.querySelectorAll(".directive-youtube
|
|
60
|
+
.querySelectorAll(".directive-youtube .consent")
|
|
61
61
|
.forEach(function (el) {
|
|
62
62
|
loadContent(el);
|
|
63
63
|
});
|
|
@@ -68,7 +68,7 @@ hyperbook.youtube.consent = (function () {
|
|
|
68
68
|
|
|
69
69
|
function init(root) {
|
|
70
70
|
var wrappers = root.querySelectorAll
|
|
71
|
-
? root.querySelectorAll(".directive-youtube
|
|
71
|
+
? root.querySelectorAll(".directive-youtube .consent")
|
|
72
72
|
: [];
|
|
73
73
|
wrappers.forEach(function (w) {
|
|
74
74
|
initWrapper(w);
|
|
@@ -14,41 +14,40 @@
|
|
|
14
14
|
height: 100%;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
.directive-youtube
|
|
17
|
+
.directive-youtube .consent {
|
|
18
18
|
position: absolute;
|
|
19
19
|
top: 0;
|
|
20
20
|
left: 0;
|
|
21
21
|
width: 100%;
|
|
22
22
|
height: 100%;
|
|
23
|
+
padding: 24px;
|
|
24
|
+
overflow: auto;
|
|
25
|
+
border: 2px solid var(--color-brand, #333);
|
|
26
|
+
border-radius: 8px;
|
|
23
27
|
}
|
|
24
28
|
|
|
25
|
-
.directive-youtube
|
|
29
|
+
.directive-youtube .consent iframe[data-consent-src] {
|
|
26
30
|
display: none;
|
|
27
31
|
}
|
|
28
32
|
|
|
29
|
-
.directive-youtube
|
|
33
|
+
.directive-youtube .consent-banner {
|
|
30
34
|
display: flex;
|
|
31
35
|
flex-direction: column;
|
|
32
36
|
align-items: center;
|
|
33
37
|
justify-content: center;
|
|
34
38
|
gap: 12px;
|
|
35
|
-
padding: 24px;
|
|
36
|
-
background-color: var(--color-background-tinted, #f5f5f5);
|
|
37
|
-
border: 2px solid var(--color-brand, #333);
|
|
38
|
-
border-radius: 8px;
|
|
39
39
|
text-align: center;
|
|
40
|
-
height: 100%;
|
|
41
40
|
box-sizing: border-box;
|
|
42
41
|
}
|
|
43
42
|
|
|
44
|
-
.directive-youtube
|
|
43
|
+
.directive-youtube .consent-banner-text {
|
|
45
44
|
font-size: 0.95em;
|
|
46
45
|
line-height: 1.5;
|
|
47
46
|
color: var(--color-text, #333);
|
|
48
47
|
max-width: 600px;
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
.directive-youtube
|
|
50
|
+
.directive-youtube .consent-always-label {
|
|
52
51
|
display: flex;
|
|
53
52
|
align-items: center;
|
|
54
53
|
gap: 6px;
|
|
@@ -57,23 +56,23 @@
|
|
|
57
56
|
cursor: pointer;
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
.directive-youtube
|
|
59
|
+
.directive-youtube .consent-always-checkbox {
|
|
61
60
|
cursor: pointer;
|
|
62
61
|
margin: 0!important;
|
|
63
62
|
vertical-align: middle;
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
.directive-youtube
|
|
65
|
+
.directive-youtube .consent-accept-btn {
|
|
67
66
|
padding: 8px 24px;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
border:
|
|
67
|
+
color: var(--color-brand);
|
|
68
|
+
background: none;
|
|
69
|
+
border: 1px solid var(--color-brand);
|
|
71
70
|
border-radius: 4px;
|
|
72
71
|
cursor: pointer;
|
|
73
72
|
font-size: 0.95em;
|
|
74
73
|
}
|
|
75
74
|
|
|
76
|
-
.directive-youtube
|
|
75
|
+
.directive-youtube .consent-accept-btn:hover {
|
|
77
76
|
opacity: 0.9;
|
|
78
77
|
}
|
|
79
78
|
|
package/dist/assets/store.js
CHANGED
|
@@ -12,7 +12,7 @@ window.hyperbook = window.hyperbook || {};
|
|
|
12
12
|
hyperbook.store = (function () {
|
|
13
13
|
/** @type {import("dexie").Dexie} */
|
|
14
14
|
var db = new Dexie("Hyperbook");
|
|
15
|
-
db.version(
|
|
15
|
+
db.version(4).stores({
|
|
16
16
|
consent: `id`,
|
|
17
17
|
currentState: `
|
|
18
18
|
id,
|
|
@@ -43,6 +43,7 @@ hyperbook.store = (function () {
|
|
|
43
43
|
onlineide: `scriptId,script`,
|
|
44
44
|
sqlideScripts: `scriptId,script`,
|
|
45
45
|
sqlideDatabases: `databaseId,database`,
|
|
46
|
+
struktolab: `id,tree`,
|
|
46
47
|
multievent: `id,state`,
|
|
47
48
|
typst: `id,code`,
|
|
48
49
|
});
|
package/dist/index.js
CHANGED
|
@@ -174627,18 +174627,18 @@ var remarkDirectiveYoutube_default = (ctx) => () => {
|
|
|
174627
174627
|
type: "element",
|
|
174628
174628
|
tagName: "div",
|
|
174629
174629
|
properties: {
|
|
174630
|
-
class: "
|
|
174630
|
+
class: "consent"
|
|
174631
174631
|
},
|
|
174632
174632
|
children: [
|
|
174633
174633
|
{
|
|
174634
174634
|
type: "element",
|
|
174635
174635
|
tagName: "div",
|
|
174636
|
-
properties: { class: "
|
|
174636
|
+
properties: { class: "consent-banner" },
|
|
174637
174637
|
children: [
|
|
174638
174638
|
{
|
|
174639
174639
|
type: "element",
|
|
174640
174640
|
tagName: "p",
|
|
174641
|
-
properties: { class: "
|
|
174641
|
+
properties: { class: "consent-banner-text" },
|
|
174642
174642
|
children: [
|
|
174643
174643
|
{
|
|
174644
174644
|
type: "text",
|
|
@@ -174649,7 +174649,7 @@ var remarkDirectiveYoutube_default = (ctx) => () => {
|
|
|
174649
174649
|
{
|
|
174650
174650
|
type: "element",
|
|
174651
174651
|
tagName: "p",
|
|
174652
|
-
properties: { class: "
|
|
174652
|
+
properties: { class: "consent-banner-text" },
|
|
174653
174653
|
children: [
|
|
174654
174654
|
{
|
|
174655
174655
|
type: "text",
|
|
@@ -174660,14 +174660,14 @@ var remarkDirectiveYoutube_default = (ctx) => () => {
|
|
|
174660
174660
|
{
|
|
174661
174661
|
type: "element",
|
|
174662
174662
|
tagName: "label",
|
|
174663
|
-
properties: { class: "
|
|
174663
|
+
properties: { class: "consent-always-label" },
|
|
174664
174664
|
children: [
|
|
174665
174665
|
{
|
|
174666
174666
|
type: "element",
|
|
174667
174667
|
tagName: "input",
|
|
174668
174668
|
properties: {
|
|
174669
174669
|
type: "checkbox",
|
|
174670
|
-
class: "
|
|
174670
|
+
class: "consent-always-checkbox"
|
|
174671
174671
|
},
|
|
174672
174672
|
children: []
|
|
174673
174673
|
},
|
|
@@ -174680,7 +174680,7 @@ var remarkDirectiveYoutube_default = (ctx) => () => {
|
|
|
174680
174680
|
{
|
|
174681
174681
|
type: "element",
|
|
174682
174682
|
tagName: "button",
|
|
174683
|
-
properties: { class: "
|
|
174683
|
+
properties: { class: "consent-accept-btn" },
|
|
174684
174684
|
children: [
|
|
174685
174685
|
{ type: "text", value: i18n.get("consent-youtube-accept") }
|
|
174686
174686
|
]
|
|
@@ -180549,19 +180549,19 @@ var remarkDirectiveEmbed_default = (ctx) => () => {
|
|
|
180549
180549
|
type: "element",
|
|
180550
180550
|
tagName: "div",
|
|
180551
180551
|
properties: {
|
|
180552
|
-
class: "
|
|
180552
|
+
class: "consent",
|
|
180553
180553
|
"data-consent-src": src
|
|
180554
180554
|
},
|
|
180555
180555
|
children: [
|
|
180556
180556
|
{
|
|
180557
180557
|
type: "element",
|
|
180558
180558
|
tagName: "div",
|
|
180559
|
-
properties: { class: "
|
|
180559
|
+
properties: { class: "consent-banner" },
|
|
180560
180560
|
children: [
|
|
180561
180561
|
{
|
|
180562
180562
|
type: "element",
|
|
180563
180563
|
tagName: "p",
|
|
180564
|
-
properties: { class: "
|
|
180564
|
+
properties: { class: "consent-banner-text" },
|
|
180565
180565
|
children: [
|
|
180566
180566
|
{
|
|
180567
180567
|
type: "text",
|
|
@@ -180607,7 +180607,7 @@ var remarkDirectiveEmbed_default = (ctx) => () => {
|
|
|
180607
180607
|
type: "element",
|
|
180608
180608
|
tagName: "label",
|
|
180609
180609
|
properties: {
|
|
180610
|
-
class: "
|
|
180610
|
+
class: "consent-always-label"
|
|
180611
180611
|
},
|
|
180612
180612
|
children: [
|
|
180613
180613
|
{
|
|
@@ -180615,7 +180615,7 @@ var remarkDirectiveEmbed_default = (ctx) => () => {
|
|
|
180615
180615
|
tagName: "input",
|
|
180616
180616
|
properties: {
|
|
180617
180617
|
type: "checkbox",
|
|
180618
|
-
class: "
|
|
180618
|
+
class: "consent-always-checkbox"
|
|
180619
180619
|
},
|
|
180620
180620
|
children: []
|
|
180621
180621
|
},
|
|
@@ -180629,7 +180629,7 @@ var remarkDirectiveEmbed_default = (ctx) => () => {
|
|
|
180629
180629
|
type: "element",
|
|
180630
180630
|
tagName: "button",
|
|
180631
180631
|
properties: {
|
|
180632
|
-
class: "
|
|
180632
|
+
class: "consent-accept-btn"
|
|
180633
180633
|
},
|
|
180634
180634
|
children: [
|
|
180635
180635
|
{
|
|
@@ -200793,6 +200793,77 @@ var remarkDirectiveTypst_default = (ctx) => () => {
|
|
|
200793
200793
|
};
|
|
200794
200794
|
};
|
|
200795
200795
|
|
|
200796
|
+
// src/remarkDirectiveStruktolab.ts
|
|
200797
|
+
var remarkDirectiveStruktolab_default = (ctx) => () => {
|
|
200798
|
+
const name = "struktolab";
|
|
200799
|
+
return (tree, file) => {
|
|
200800
|
+
visit(tree, function(node3) {
|
|
200801
|
+
if (isDirective(node3)) {
|
|
200802
|
+
if (node3.name !== name) return;
|
|
200803
|
+
const data = node3.data || (node3.data = {});
|
|
200804
|
+
const {
|
|
200805
|
+
id = hash(node3),
|
|
200806
|
+
lang: lang248 = ctx.config.language,
|
|
200807
|
+
colorMode = "color",
|
|
200808
|
+
fontSize = 14,
|
|
200809
|
+
scale = 1,
|
|
200810
|
+
src,
|
|
200811
|
+
mode = "preview"
|
|
200812
|
+
// "preview" or "edit"
|
|
200813
|
+
} = node3.attributes || {};
|
|
200814
|
+
expectLeafDirective(node3, file, name);
|
|
200815
|
+
registerDirective(
|
|
200816
|
+
file,
|
|
200817
|
+
name,
|
|
200818
|
+
["client.js", "struktolab-renderer.umd.js", "struktolab-editor.umd.js"],
|
|
200819
|
+
["style.css"],
|
|
200820
|
+
[]
|
|
200821
|
+
);
|
|
200822
|
+
let webcomponent = "struktolab-renderer";
|
|
200823
|
+
if (mode === "edit") {
|
|
200824
|
+
webcomponent = "struktolab-editor";
|
|
200825
|
+
}
|
|
200826
|
+
const codes = node3.children?.filter(isCode).map((n) => ({
|
|
200827
|
+
type: "element",
|
|
200828
|
+
tagName: "script",
|
|
200829
|
+
properties: {
|
|
200830
|
+
type: "text/pseudocode"
|
|
200831
|
+
},
|
|
200832
|
+
children: [
|
|
200833
|
+
{
|
|
200834
|
+
type: "text",
|
|
200835
|
+
value: n.value
|
|
200836
|
+
}
|
|
200837
|
+
]
|
|
200838
|
+
}));
|
|
200839
|
+
data.hName = "div";
|
|
200840
|
+
data.hProperties = {
|
|
200841
|
+
class: "directive-struktolab"
|
|
200842
|
+
};
|
|
200843
|
+
data.hChildren = [
|
|
200844
|
+
{
|
|
200845
|
+
type: "element",
|
|
200846
|
+
tagName: webcomponent,
|
|
200847
|
+
properties: {
|
|
200848
|
+
lang: lang248,
|
|
200849
|
+
"color-mode": colorMode,
|
|
200850
|
+
"font-size": fontSize,
|
|
200851
|
+
"scale": scale,
|
|
200852
|
+
"data-id": id,
|
|
200853
|
+
src: src ? ctx.makeUrl(
|
|
200854
|
+
src,
|
|
200855
|
+
"public",
|
|
200856
|
+
ctx.navigation.current || void 0
|
|
200857
|
+
) : void 0
|
|
200858
|
+
},
|
|
200859
|
+
children: [...codes]
|
|
200860
|
+
}
|
|
200861
|
+
];
|
|
200862
|
+
}
|
|
200863
|
+
});
|
|
200864
|
+
};
|
|
200865
|
+
};
|
|
200866
|
+
|
|
200796
200867
|
// src/process.ts
|
|
200797
200868
|
var remark = (ctx) => {
|
|
200798
200869
|
i18n.init(ctx.config.language || "en");
|
|
@@ -200830,6 +200901,7 @@ var remark = (ctx) => {
|
|
|
200830
200901
|
remarkDirectiveAbcMusic_default(ctx),
|
|
200831
200902
|
remarkDirectiveExcalidraw_default(ctx),
|
|
200832
200903
|
remarkDirectiveStruktog_default(ctx),
|
|
200904
|
+
remarkDirectiveStruktolab_default(ctx),
|
|
200833
200905
|
remarkDirectiveGeogebra_default(ctx),
|
|
200834
200906
|
remarkDirectiveH5P_default(ctx),
|
|
200835
200907
|
remarkDirectiveJSXGraph_default(ctx),
|
|
@@ -200952,7 +201024,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"application/1d-interleaved-parityfec
|
|
|
200952
201024
|
/***/ ((module) => {
|
|
200953
201025
|
|
|
200954
201026
|
"use strict";
|
|
200955
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"hyperbook","version":"0.
|
|
201027
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"hyperbook","version":"0.86.1","author":"Mike Barkmin","homepage":"https://github.com/openpatch/hyperbook#readme","license":"MIT","bin":{"hyperbook":"./dist/index.js"},"files":["dist"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/openpatch/hyperbook.git","directory":"packages/hyperbook"},"bugs":{"url":"https://github.com/openpatch/hyperbook/issues"},"engines":{"node":">=18"},"scripts":{"version":"pnpm build","lint":"tsc --noEmit","dev":"ncc build ./index.ts -w -o dist/","build":"rimraf dist && ncc build ./index.ts -o ./dist/ --no-cache --no-source-map-register --external favicons --external sharp && node postbuild.mjs"},"dependencies":{"favicons":"^7.2.0"},"devDependencies":{"create-hyperbook":"workspace:*","@hyperbook/fs":"workspace:*","@hyperbook/markdown":"workspace:*","@hyperbook/types":"workspace:*","@pnpm/exportable-manifest":"1000.0.6","@types/archiver":"6.0.3","@types/async-retry":"1.4.9","@types/cross-spawn":"6.0.6","@types/lunr":"^2.3.7","@types/prompts":"2.4.9","@types/tar":"6.1.13","@types/ws":"^8.5.14","@vercel/ncc":"0.38.3","archiver":"7.0.1","async-retry":"1.3.3","chalk":"5.4.1","chokidar":"4.0.3","commander":"12.1.0","cpy":"11.1.0","cross-spawn":"7.0.6","domutils":"^3.2.2","extract-zip":"^2.0.1","got":"12.6.0","htmlparser2":"^10.0.0","lunr":"^2.3.9","lunr-languages":"^1.14.0","mime":"^4.0.6","prompts":"2.4.2","rimraf":"6.0.1","tar":"7.4.3","update-check":"1.5.4","ws":"^8.18.0"}}');
|
|
200956
201028
|
|
|
200957
201029
|
/***/ })
|
|
200958
201030
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hyperbook",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.86.1",
|
|
4
4
|
"author": "Mike Barkmin",
|
|
5
5
|
"homepage": "https://github.com/openpatch/hyperbook#readme",
|
|
6
6
|
"license": "MIT",
|
|
@@ -56,9 +56,9 @@
|
|
|
56
56
|
"tar": "7.4.3",
|
|
57
57
|
"update-check": "1.5.4",
|
|
58
58
|
"ws": "^8.18.0",
|
|
59
|
-
"@hyperbook/
|
|
60
|
-
"@hyperbook/markdown": "0.57.0",
|
|
59
|
+
"@hyperbook/markdown": "0.58.1",
|
|
61
60
|
"@hyperbook/fs": "0.24.2",
|
|
61
|
+
"@hyperbook/types": "0.22.1",
|
|
62
62
|
"create-hyperbook": "0.3.5"
|
|
63
63
|
},
|
|
64
64
|
"scripts": {
|