Built static site
diff --git a/live/etl.js b/live/etl.js
new file mode 100644
index 0000000..45a4472
--- /dev/null
+++ b/live/etl.js
@@ -0,0 +1,107 @@
+define("ace/mode/etl_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
+
+var etlHighlightRules = function() {
+
+    var keywords = (
+        "rule|transform|from|to|guard|not|delete|import|for|while|in|and|or|operation|return|var|throw|if|new|else|transaction|abort|break|continue|assert|assertError|not|function|default|switch|case|as|ext|driver|alias|model|breakAll|async|group|nor|xor|implies"
+    );
+
+    var builtinConstants = (
+        "true|false|self"
+    );
+
+    var builtinFunctions = (
+        ""
+    );
+
+    var dataTypes = (
+        "Any|String|Integer|Real|Boolean|Native|Bag|Set|List|Sequence|Map|OrderedSet|Collection|Tuple|ConcurrentBag|ConcurrentMap|ConcurrentSet"
+    );
+
+    var keywordMapper = this.createKeywordMapper({
+        "support.function": builtinFunctions,
+        "keyword": keywords,
+        "constant.language": builtinConstants,
+        "storage.type": dataTypes
+    }, "identifier", true);
+
+    this.$rules = {
+        "start" : [ {
+            token : "comment",
+            regex : "//.*$"
+        },  {
+            token : "comment",
+            start : "/\\*",
+            end : "\\*/"
+        }, {
+            token : "string",           // " string
+            regex : '".*?"'
+        }, {
+            token : "string",           // ' string
+            regex : "'.*?'"
+        }, {
+            token : "string",           // ` string (apache drill)
+            regex : "`.*?`"
+        }, {
+            token : "constant.numeric", // float
+            regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
+        }, {
+            token : keywordMapper,
+            regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
+        }, {
+            token : "keyword.operator",
+            regex : "\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|="
+        }, {
+            token : "paren.lparen",
+            regex : "[\\(]"
+        }, {
+            token : "paren.rparen",
+            regex : "[\\)]"
+        }, {
+            token : "text",
+            regex : "\\s+"
+        } ]
+    };
+    this.normalizeRules();
+};
+
+oop.inherits(etlHighlightRules, TextHighlightRules);
+
+exports.etlHighlightRules = etlHighlightRules;
+});
+
+define("ace/mode/etl",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/etl_highlight_rules"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var TextMode = require("./text").Mode;
+var etlHighlightRules = require("./etl_highlight_rules").etlHighlightRules;
+
+var Mode = function() {
+    this.HighlightRules = etlHighlightRules;
+    this.$behaviour = this.$defaultBehaviour;
+};
+oop.inherits(Mode, TextMode);
+
+(function() {
+
+    this.lineCommentStart = "--";
+
+    this.$id = "ace/mode/etl";
+    this.snippetFileId = "ace/snippets/etl";
+}).call(Mode.prototype);
+
+exports.Mode = Mode;
+
+});                (function() {
+                    window.require(["ace/mode/etl"], function(m) {
+                        if (typeof module == "object" && typeof exports == "object" && module) {
+                            module.exports = m;
+                        }
+                    });
+                })();
+            
\ No newline at end of file
diff --git a/live/index.html b/live/index.html
index e295f09..6fad0cd 100644
--- a/live/index.html
+++ b/live/index.html
@@ -9,18 +9,31 @@
     
 	<script>
 
-    function buttonHtml(icon, hint) {
-        return "<span class='mif-" + icon + "' data-role='hint' data-hint-text='" + hint + "' data-hint-position='bottom'></span>";
+    var language = "eol";
+    
+    var url = window.location + "";
+    var questionMark = url.indexOf("?");
+    var content = "eyJlb2wiOiIvLyBGb3IgZXZlcnkgdGFzayBpbiB0aGUgbW9kZWxcbmZvciAodCBpbiBUYXNrLmFsbCkge1xuICAgIC8vIFByaW50IHRoZSB0aXRsZSBhbmQgdGhlIHRvdGFsIHBlcnNvbi1tb250aHMgb2YgdGhlIHRhc2tcbiAgICAodC50aXRsZSArIFwiOiBcIiArIHQuZ2V0VG90YWxFZmZvcnQoKSkucHJpbnRsbigpO1xufVxuXG4vLyBDb3VudCB0aGUgdGFza3MgdGhhdCBhcmUgdW5kZXJ0YWtlbiBieSBhIHNpbmdsZSBwZXJzb25cblRhc2suYWxsLnNlbGVjdCh0fHQuZWZmb3J0LnNpemUoKSA9IDEpLnNpemUoKS5cbiAgICBwcmludGxuKFwiT25lLXBlcnNvbiB0YXNrczogXCIpO1xuXG4vLyBSZXR1cm5zIHRoZSB0b3RhbCBwZXJzb24tbW9udGhzIGZvciBhIHRhc2tcbm9wZXJhdGlvbiBUYXNrIGdldFRvdGFsRWZmb3J0KCkge1xuICAgIHJldHVybiBzZWxmLmVmZm9ydC5jb2xsZWN0KGV8c2VsZi5kdXJhdGlvbiplLnBlcmNlbnRhZ2UvMTAwLjApLnN1bSgpO1xufSIsImVtZmF0aWMiOiJAbmFtZXNwYWNlKHVyaT1cInBzbFwiLCBwcmVmaXg9XCJcIilcbnBhY2thZ2UgcHNsO1xuXG5jbGFzcyBQcm9qZWN0IHtcbiAgYXR0ciBTdHJpbmcgbmFtZTtcbiAgYXR0ciBTdHJpbmcgZGVzY3JpcHRpb247XG4gIHZhbCBUYXNrWypdIHRhc2tzO1xuICB2YWwgUGVyc29uWypdIHBlb3BsZTtcbn1cblxuY2xhc3MgVGFzayB7XG4gIGF0dHIgU3RyaW5nIHRpdGxlO1xuICBhdHRyIGludCBzdGFydDtcbiAgYXR0ciBpbnQgZHVyYXRpb247XG4gIHZhbCBFZmZvcnRbKl0gZWZmb3J0O1xufVxuXG5jbGFzcyBQZXJzb24ge1xuICBhdHRyIFN0cmluZyBuYW1lO1xufVxuXG5jbGFzcyBFZmZvcnQge1xuICByZWYgUGVyc29uIHBlcnNvbjtcbiAgYXR0ciBpbnQgcGVyY2VudGFnZSA9IDEwMDtcbn0iLCJmbGV4bWkiOiI8P25zdXJpIHBzbD8+XG48cHJvamVjdCB0aXRsZT1cIkFDTUVcIj5cbiAgPHBlcnNvbiBuYW1lPVwiQWxpY2VcIi8+XG4gIDxwZXJzb24gbmFtZT1cIkJvYlwiLz5cbiAgPHRhc2sgdGl0bGU9XCJBbmFseXNpc1wiIHN0YXJ0PVwiMVwiIGR1cj1cIjNcIj5cbiAgICA8ZWZmb3J0IHBlcnNvbj1cIkFsaWNlXCIvPlxuICA8L3Rhc2s+XG4gIDx0YXNrIHRpdGxlPVwiRGVzaWduXCIgc3RhcnQ9XCI0XCIgZHVyPVwiNlwiPlxuICAgIDxlZmZvcnQgcGVyc29uPVwiQm9iXCIvPlxuICA8L3Rhc2s+XG4gIDx0YXNrIHRpdGxlPVwiSW1wbGVtZW50YXRpb25cIiBzdGFydD1cIjdcIiBkdXI9XCIzXCI+XG4gICAgPGVmZm9ydCBwZXJzb249XCJCb2JcIiBwZXJjPVwiNTBcIi8+XG4gICAgPGVmZm9ydCBwZXJzb249XCJBbGljZVwiIHBlcmM9XCI1MFwiLz5cbiAgPC90YXNrPlxuPC9wcm9qZWN0PlxuIn0=";
+
+    if (questionMark > -1) {
+        content = url.substring(questionMark+1, url.length);
     }
 
+    var json = JSON.parse(atob(content));
+    if (json.eol != null) { json.program = json.eol; language = "eol";}
+    else {language = json.language};
+
+    var languageName = (language == "flock" ? "Flock" : language.toUpperCase());
+    var secondModelEditable = !(language == "etl" || language == "flock");
+
     var programPanelButtons = [{
-        html: buttonHtml("help", "EOL language reference"),
+        html: buttonHtml("help", languageName + " language reference"),
         cls: "sys-button",
-        onclick: "window.open('https://www.eclipse.org/epsilon/doc/eol');"
+        onclick: "window.open('https://www.eclipse.org/epsilon/doc/'+language);"
     },{
-        html: buttonHtml("play", "Run the EOL program"),
+        html: buttonHtml("play", "Run the program"),
         cls: "success",
-        onclick: "runEol()"
+        onclick: "runProgram()"
     }];
     var modelPanelButtons = [{
         html: buttonHtml("help", "Flexmi language reference"),
@@ -48,11 +61,43 @@
         cls: "sys-button",
         onclick: "toggle('metamodelDiagram', function(){refreshMetamodelDiagram();})"
     }];
+    var secondModelPanelButtons = secondModelEditable ? [{
+        html: buttonHtml("help", "Flexmi language reference"),
+        cls: "sys-button",
+        onclick: "window.open('https://www.eclipse.org/epsilon/doc/flexmi');"
+    },{
+        html: buttonHtml("refresh", "Render the model diagram"),
+        cls: "sys-button",
+        onclick: "refreshSecondModelDiagram()"
+    },{
+        html: buttonHtml("tree", "Show/hide the model diagram"),
+        cls: "sys-button",
+        onclick: "toggle('secondModelDiagram', function(){})"
+    }] : [];
+    var secondMetamodelPanelButtons = [{
+        html: buttonHtml("help", "Emfatic language reference"),
+        cls: "sys-button",
+        onclick: "window.open('https://www.eclipse.org/emfatic');"
+    },{
+        html: buttonHtml("refresh", "Render the metamodel diagram"),
+        cls: "sys-button",
+        onclick: "refreshSecondMetamodelDiagram()"
+    },{
+        html: buttonHtml("tree", "Show/hide the metamodel diagram"),
+        cls: "sys-button",
+        onclick: "toggle('secondMetamodelDiagram', function(){refreshSecondMetamodelDiagram();})"
+    }];
+    var thirdModelPanelButtons = [];
     var consolePanelButtons = [{
         html: buttonHtml("cross", "Clear the console"),
         cls: "sys-button",
         onclick: "consoleEditor.setValue('')"
     }];
+
+    function buttonHtml(icon, hint) {
+        return "<span class='mif-" + icon + "' data-role='hint' data-hint-text='" + hint + "' data-hint-position='bottom'></span>";
+    }
+
     </script>
 </head>
 
@@ -65,6 +110,27 @@
             <ul class="navview-menu">
                 <li class="item-header">Epsilon Playground</li>
                 <li>
+                    <a href="?eyJsYW5ndWFnZSI6ImVvbCIsImVvbCI6Ii8vIEZvciBldmVyeSB0YXNrIGluIHRoZSBtb2RlbFxuZm9yICh0IGluIFRhc2suYWxsKSB7XG4gICAgLy8gUHJpbnQgdGhlIHRpdGxlIGFuZCB0aGUgdG90YWwgcGVyc29uLW1vbnRocyBvZiB0aGUgdGFza1xuICAgICh0LnRpdGxlICsgXCI6IFwiICsgdC5nZXRUb3RhbEVmZm9ydCgpKS5wcmludGxuKCk7XG59XG5cbi8vIENvdW50IHRoZSB0YXNrcyB0aGF0IGFyZSB1bmRlcnRha2VuIGJ5IGEgc2luZ2xlIHBlcnNvblxuVGFzay5hbGwuc2VsZWN0KHR8dC5lZmZvcnQuc2l6ZSgpID0gMSkuc2l6ZSgpLlxuICAgIHByaW50bG4oXCJPbmUtcGVyc29uIHRhc2tzOiBcIik7XG5cbi8vIFJldHVybnMgdGhlIHRvdGFsIHBlcnNvbi1tb250aHMgZm9yIGEgdGFza1xub3BlcmF0aW9uIFRhc2sgZ2V0VG90YWxFZmZvcnQoKSB7XG4gICAgcmV0dXJuIHNlbGYuZWZmb3J0LmNvbGxlY3QoZXxzZWxmLmR1cmF0aW9uKmUucGVyY2VudGFnZS8xMDAuMCkuc3VtKCk7XG59IiwiZW1mYXRpYyI6IkBuYW1lc3BhY2UodXJpPVwicHNsXCIsIHByZWZpeD1cIlwiKVxucGFja2FnZSBwc2w7XG5cbmNsYXNzIFByb2plY3Qge1xuICBhdHRyIFN0cmluZyBuYW1lO1xuICBhdHRyIFN0cmluZyBkZXNjcmlwdGlvbjtcbiAgdmFsIFRhc2tbKl0gdGFza3M7XG4gIHZhbCBQZXJzb25bKl0gcGVvcGxlO1xufVxuXG5jbGFzcyBUYXNrIHtcbiAgYXR0ciBTdHJpbmcgdGl0bGU7XG4gIGF0dHIgaW50IHN0YXJ0O1xuICBhdHRyIGludCBkdXJhdGlvbjtcbiAgdmFsIEVmZm9ydFsqXSBlZmZvcnQ7XG59XG5cbmNsYXNzIFBlcnNvbiB7XG4gIGF0dHIgU3RyaW5nIG5hbWU7XG59XG5cbmNsYXNzIEVmZm9ydCB7XG4gIHJlZiBQZXJzb24gcGVyc29uO1xuICBhdHRyIGludCBwZXJjZW50YWdlID0gMTAwO1xufSIsImZsZXhtaSI6Ijw/bnN1cmkgcHNsPz5cbjxwcm9qZWN0IHRpdGxlPVwiQUNNRVwiPlxuICA8cGVyc29uIG5hbWU9XCJBbGljZVwiLz5cbiAgPHBlcnNvbiBuYW1lPVwiQm9iXCIvPlxuICA8dGFzayB0aXRsZT1cIkFuYWx5c2lzXCIgc3RhcnQ9XCIxXCIgZHVyPVwiM1wiPlxuICAgIDxlZmZvcnQgcGVyc29uPVwiQWxpY2VcIi8+XG4gIDwvdGFzaz5cbiAgPHRhc2sgdGl0bGU9XCJEZXNpZ25cIiBzdGFydD1cIjRcIiBkdXI9XCI2XCI+XG4gICAgPGVmZm9ydCBwZXJzb249XCJCb2JcIi8+XG4gIDwvdGFzaz5cbiAgPHRhc2sgdGl0bGU9XCJJbXBsZW1lbnRhdGlvblwiIHN0YXJ0PVwiN1wiIGR1cj1cIjNcIj5cbiAgICA8ZWZmb3J0IHBlcnNvbj1cIkJvYlwiIHBlcmM9XCI1MFwiLz5cbiAgICA8ZWZmb3J0IHBlcnNvbj1cIkFsaWNlXCIgcGVyYz1cIjUwXCIvPlxuICA8L3Rhc2s+XG48L3Byb2plY3Q+XG4iLCJzZWNvbmRFbWZhdGljIjoidW5kZWZpbmVkIiwic2Vjb25kRmxleG1pIjoidW5kZWZpbmVkIn0=">
+                        <span class="icon"><span class="mif-apps"></span></span>
+                        <span class="caption">Project Plan Queries</span>
+                        <div class="badges">
+                            <span class="badge inline">EOL</span>
+                        </div>
+                    </a>
+                    <a href="?eyJsYW5ndWFnZSI6ImV0bCIsInByb2dyYW0iOiJydWxlIFRyZWUyR3JhcGhcbiAgICB0cmFuc2Zvcm0gcyA6IFNvdXJjZSFUcmVlXG4gICAgdG8gdCA6IFRhcmdldCFHcmFwaCB7XG4gICAgXG4gICAgZ3VhcmQ6IG5vdCBzLnBhcmVudC5pc0RlZmluZWQoKVxuICAgIFxuICAgIHQubmFtZSA9IHMubGFiZWw7XG59XG5cbnJ1bGUgVHJlZTJOb2RlQW5kRWRnZVxuICAgIHRyYW5zZm9ybSBzIDogU291cmNlIVRyZWVcbiAgICB0byBuIDogVGFyZ2V0IU5vZGUge1xuICAgICAgICAgICBcbiAgICBndWFyZDogcy5wYXJlbnQuaXNEZWZpbmVkKClcbiAgICBcbiAgICBuLm5hbWUgPSBzLmxhYmVsO1xuICAgIHZhciBncmFwaCA9IFRhcmdldCFHcmFwaC5hbGwuZmlyc3QoKTtcbiAgICBcbiAgICBpZiAocy5wYXJlbnQucGFyZW50LmlzRGVmaW5lZCgpKSB7XG4gICAgICAgIHZhciBlIDogbmV3IFRhcmdldCFFZGdlO1xuICAgICAgICBlLnNvdXJjZSA6Oj0gcy5wYXJlbnQ7XG4gICAgICAgIGUudGFyZ2V0ID0gbjtcbiAgICAgICAgZ3JhcGguZWRnZXMuYWRkKGUpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZ3JhcGgubm9kZXMuYWRkKG4pO1xuICAgIH1cbn0iLCJlbWZhdGljIjoicGFja2FnZSB0cmVlO1xuXG5jbGFzcyBUcmVlIHtcbiAgICBhdHRyIFN0cmluZyBsYWJlbDtcbiAgICB2YWwgVHJlZVsqXSNwYXJlbnQgY2hpbGRyZW47XG4gICAgcmVmIFRyZWUjY2hpbGRyZW4gcGFyZW50O1xufSIsImZsZXhtaSI6Ijw/bnN1cmkgdHJlZT8+XG48dHJlZSBsYWJlbD1cInQxXCI+XG4gICAgPHRyZWUgbGFiZWw9XCJ0MlwiPlxuICAgICAgICA8dHJlZSBsYWJlbD1cInQzXCIvPlxuICAgICAgICA8dHJlZSBsYWJlbD1cInQ0XCIvPlxuICAgIDwvdHJlZT5cbjwvdHJlZT4iLCJzZWNvbmRFbWZhdGljIjoicGFja2FnZSBncmFwaDtcblxuY2xhc3MgR3JhcGgge1xuICAgIGF0dHIgU3RyaW5nIG5hbWU7XG4gICAgdmFsIE5vZGVbKl0gbm9kZXM7XG4gICAgdmFsIEVkZ2VbKl0gZWRnZXM7XG59XG5cbmNsYXNzIE5vZGUge1xuICAgIGF0dHIgU3RyaW5nIG5hbWU7XG59XG5cbmNsYXNzIEVkZ2Uge1xuICAgIHJlZiBOb2RlIHNvdXJjZTtcbiAgICByZWYgTm9kZSB0YXJnZXQ7XG59Iiwic2Vjb25kRmxleG1pIjoidW5kZWZpbmVkIn0=">
+                        <span class="icon"><span class="mif-apps"></span></span>
+                        <span class="caption">Tree to Graph</span>
+                        <div class="badges">
+                            <span class="badge inline">ETL</span>
+                        </div>
+                    </a>
+                    <!--a href="?eyJsYW5ndWFnZSI6ImV2bCJ9">
+                        <span class="icon"><span class="mif-apps"></span></span>
+                        <span class="caption">Empty EVL</span>
+                        <div class="badges">
+                            <span class="badge inline">EVL</span>
+                        </div>
+                    </a-->
                     <a href="#" id="exampleLink">
                         <span class="icon"><span class="mif-link"></span></span>
                         <span class="caption">Link to this example</span>
@@ -76,27 +142,46 @@
         <div class="navview-content">
             <div id="splitter" data-role="splitter" class="h-100" style="min-height:800px">
                 <div data-role="splitter" data-split-mode="vertical">
-                    <div id="EOL" data-role="panel" data-title-caption="Program (EOL)" data-title-icon="<span class='mif-apps'></span>" data-custom-buttons="programPanelButtons">
-                        <div class="editor" id="eolEditor"></div>
+                    <div id="programPanel" data-role="panel" data-title-caption="Program (EOL)" data-title-icon="<span class='mif-apps'></span>" data-custom-buttons="programPanelButtons">
+                        <div class="editor" id="programEditor"></div>
                     </div>
                     <div data-role="panel" data-title-caption="Console" data-title-icon="<span class='mif-display'></span>" data-custom-buttons="consolePanelButtons">
                         <div class="editor" id="console"></div>
                     </div>
                 </div>
                 <div data-role="splitter" data-split-mode="vertical">
-                    <div data-role="panel" data-title-caption="Model (Flexmi)" data-title-icon="<span class='mif-cloud'></span>" data-custom-buttons="modelPanelButtons">
+                    <div id="modelPanel" data-role="panel" data-title-caption="Model (Flexmi)" data-title-icon="<span class='mif-cloud'></span>" data-custom-buttons="modelPanelButtons">
                         <div data-role="splitter" class="h-100">
                             <div class="editor" id="flexmiEditor"></div>
                             <div id="modelDiagram" style="display:none;"></div>
                         </div>
                     </div>
-                    <div data-role="panel" data-title-caption="Metamodel (Emfatic)" data-title-icon="<span class='mif-cloud3'></span>" data-custom-buttons="metamodelPanelButtons">
+                    <div id="metamodelPanel" data-role="panel" data-title-caption="Metamodel (Emfatic)" data-title-icon="<span class='mif-cloud3'></span>" data-custom-buttons="metamodelPanelButtons">
                         <div data-role="splitter" class="h-100">
                             <div class="editor" id="emfaticEditor"></div>
                             <div id="metamodelDiagram" style="display:none;"></div>
                         </div>
                     </div>
                 </div>
+                <div data-role="splitter" data-split-mode="vertical" id="secondModelSplitter">
+                    <div id="secondModelPanel" data-role="panel" data-title-caption="Second Model (Flexmi)" data-title-icon="<span class='mif-cloud'></span>" data-custom-buttons="secondModelPanelButtons">
+                        <div data-role="splitter" class="h-100">
+                            <div class="editor" id="secondFlexmiEditor"></div>
+                            <div id="secondModelDiagram" style="display:none;"></div>
+                        </div>
+                    </div>
+                    <div id="secondMetamodelPanel" data-role="panel" data-title-caption="Second Metamodel (Emfatic)" data-title-icon="<span class='mif-cloud3'></span>" data-custom-buttons="secondMetamodelPanelButtons">
+                        <div data-role="splitter" class="h-100">
+                            <div class="editor" id="secondEmfaticEditor"></div>
+                            <div id="secondMetamodelDiagram" style="display:none;"></div>
+                        </div>
+                    </div>
+                </div>
+                <div data-role="splitter" data-split-mode="vertical" id="thirdModelSplitter">
+                    <div id="thirdModelPanel" data-role="panel" data-title-caption="Model (Flexmi)" data-title-icon="<span class='mif-cloud'></span>" data-custom-buttons="thirdModelPanelButtons">
+                        <div id="thirdModelDiagram" style="display:none;"></div>
+                    </div>
+                </div>
             </div>
         </div>
     </div>
@@ -106,6 +191,7 @@
     <script src="https://cdn.metroui.org.ua/v4/js/metro.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.11/ace.js" type="text/javascript" charset="utf-8"></script>
     <script src="eol.js" type="text/javascript"></script>
+    <script src="etl.js" type="text/javascript"></script>
     <script src="emfatic.js" type="text/javascript"></script>
     
     <script>
@@ -117,56 +203,111 @@
         editor.setFontSize("1rem");
     });
 
-    var eolEditor = ace.edit(document.getElementById('eolEditor'));
+    var programEditor = ace.edit(document.getElementById('programEditor'));
     var flexmiEditor = ace.edit(document.getElementById('flexmiEditor'));
     var emfaticEditor = ace.edit(document.getElementById('emfaticEditor'));
+    var secondFlexmiEditor = ace.edit(document.getElementById('secondFlexmiEditor'));
+    var secondEmfaticEditor = ace.edit(document.getElementById('secondEmfaticEditor'));
     var consoleEditor = ace.edit(document.getElementById('console'));
 
-    eolEditor.setShowPrintMargin(false);
-    flexmiEditor.setShowPrintMargin(false);
-    emfaticEditor.setShowPrintMargin(false);
-    consoleEditor.setShowPrintMargin(false);
+    var editors = [programEditor, flexmiEditor, emfaticEditor, secondFlexmiEditor, secondEmfaticEditor, consoleEditor];
 
-    eolEditor.getSession().setMode("ace/mode/eol");
-
-    console.log(eolEditor.getSession().getMode());
+    editors.forEach(e => e.setShowPrintMargin(false));
 
     emfaticEditor.getSession().setMode("ace/mode/emfatic");
     flexmiEditor.getSession().setMode("ace/mode/xml");
+    secondEmfaticEditor.getSession().setMode("ace/mode/emfatic");
+    secondFlexmiEditor.getSession().setMode("ace/mode/xml");
     consoleEditor.setReadOnly(true);
 
-    eolEditor.getSession().on('change', function() {
-        updateExampleLink();
-    });
-    flexmiEditor.getSession().on('change', function() {
-        updateExampleLink();
-    });
-    emfaticEditor.getSession().on('change', function() {
-        updateExampleLink();
-    });
+    editors.forEach(e => e.getSession().on('change', function() { updateExampleLink(); }));
 
-    var url = window.location + "";
-    var questionMark = url.indexOf("?");
-    var content = "eyJlb2wiOiIvLyBGb3IgZXZlcnkgdGFzayBpbiB0aGUgbW9kZWxcbmZvciAodCBpbiBUYXNrLmFsbCkge1xuICAgIC8vIFByaW50IHRoZSB0aXRsZSBhbmQgdGhlIHRvdGFsIHBlcnNvbi1tb250aHMgb2YgdGhlIHRhc2tcbiAgICAodC50aXRsZSArIFwiOiBcIiArIHQuZ2V0VG90YWxFZmZvcnQoKSkucHJpbnRsbigpO1xufVxuXG4vLyBDb3VudCB0aGUgdGFza3MgdGhhdCBhcmUgdW5kZXJ0YWtlbiBieSBhIHNpbmdsZSBwZXJzb25cblRhc2suYWxsLnNlbGVjdCh0fHQuZWZmb3J0LnNpemUoKSA9IDEpLnNpemUoKS5cbiAgICBwcmludGxuKFwiT25lLXBlcnNvbiB0YXNrczogXCIpO1xuXG4vLyBSZXR1cm5zIHRoZSB0b3RhbCBwZXJzb24tbW9udGhzIGZvciBhIHRhc2tcbm9wZXJhdGlvbiBUYXNrIGdldFRvdGFsRWZmb3J0KCkge1xuICAgIHJldHVybiBzZWxmLmVmZm9ydC5jb2xsZWN0KGV8c2VsZi5kdXJhdGlvbiplLnBlcmNlbnRhZ2UvMTAwLjApLnN1bSgpO1xufSIsImVtZmF0aWMiOiJAbmFtZXNwYWNlKHVyaT1cInBzbFwiLCBwcmVmaXg9XCJcIilcbnBhY2thZ2UgcHNsO1xuXG5jbGFzcyBQcm9qZWN0IHtcbiAgYXR0ciBTdHJpbmcgbmFtZTtcbiAgYXR0ciBTdHJpbmcgZGVzY3JpcHRpb247XG4gIHZhbCBUYXNrWypdIHRhc2tzO1xuICB2YWwgUGVyc29uWypdIHBlb3BsZTtcbn1cblxuY2xhc3MgVGFzayB7XG4gIGF0dHIgU3RyaW5nIHRpdGxlO1xuICBhdHRyIGludCBzdGFydDtcbiAgYXR0ciBpbnQgZHVyYXRpb247XG4gIHZhbCBFZmZvcnRbKl0gZWZmb3J0O1xufVxuXG5jbGFzcyBQZXJzb24ge1xuICBhdHRyIFN0cmluZyBuYW1lO1xufVxuXG5jbGFzcyBFZmZvcnQge1xuICByZWYgUGVyc29uIHBlcnNvbjtcbiAgYXR0ciBpbnQgcGVyY2VudGFnZSA9IDEwMDtcbn0iLCJmbGV4bWkiOiI8P25zdXJpIHBzbD8+XG48cHJvamVjdCB0aXRsZT1cIkFDTUVcIj5cbiAgPHBlcnNvbiBuYW1lPVwiQWxpY2VcIi8+XG4gIDxwZXJzb24gbmFtZT1cIkJvYlwiLz5cbiAgPHRhc2sgdGl0bGU9XCJBbmFseXNpc1wiIHN0YXJ0PVwiMVwiIGR1cj1cIjNcIj5cbiAgICA8ZWZmb3J0IHBlcnNvbj1cIkFsaWNlXCIvPlxuICA8L3Rhc2s+XG4gIDx0YXNrIHRpdGxlPVwiRGVzaWduXCIgc3RhcnQ9XCI0XCIgZHVyPVwiNlwiPlxuICAgIDxlZmZvcnQgcGVyc29uPVwiQm9iXCIvPlxuICA8L3Rhc2s+XG4gIDx0YXNrIHRpdGxlPVwiSW1wbGVtZW50YXRpb25cIiBzdGFydD1cIjdcIiBkdXI9XCIzXCI+XG4gICAgPGVmZm9ydCBwZXJzb249XCJCb2JcIiBwZXJjPVwiNTBcIi8+XG4gICAgPGVmZm9ydCBwZXJzb249XCJBbGljZVwiIHBlcmM9XCI1MFwiLz5cbiAgPC90YXNrPlxuPC9wcm9qZWN0PlxuIn0=";
+   
+    //console.log(language);
+    arrangePanels();
+    console.log(btoa(JSON.stringify({"language":"evl"})));
 
-    if (questionMark > -1) {
-        content = url.substring(questionMark+1, url.length);
-    }
-
-    var json = JSON.parse(atob(content));
-    eolEditor.setValue(json.eol, 1);
-    flexmiEditor.setValue(json.flexmi, 1);
-    emfaticEditor.setValue(json.emfatic, 1);
+    //TODO: Fix "undefined" when fields are empty
+    programEditor.getSession().setMode("ace/mode/" + language);
+    programEditor.setValue(json.program + "", 1);
+    flexmiEditor.setValue(json.flexmi + "", 1);
+    emfaticEditor.setValue(json.emfatic + "", 1);
+    secondFlexmiEditor.setValue(json.secondFlexmi + "", 1);
+    secondEmfaticEditor.setValue(json.secondEmfatic + "", 1);
     consoleEditor.setValue("",1);
     
+    //document.getElementById("secondModelSplitter").style.display = "none";
+    //document.getElementById("secondMetamodelDiagram").style.display = "none";
+    //toggle("secondModelPanel", function(){window.alert();});
+
     setInterval(fit, 100);
 
     function updateExampleLink() {
         document.getElementById('exampleLink').href = "?" + btoa(editorsToJson());
     }
 
+    function arrangePanels() {
+        if (language == "eol" || language == "egl") {
+            toggle("secondModelSplitter");
+            toggle("thirdModelSplitter");
+            setPanelTitle("programPanel", "Program");
+        }
+        else if (language == "etl" || language == "flock") {
+            $("#thirdModelSplitter").hide();
+            $("#secondModelDiagram").show();
+            $("#secondFlexmiEditor").hide();
+
+            setPanelTitle("programPanel", "Transformation");
+            setPanelTitle("modelPanel", "Source Model (Flexmi)");
+            setPanelTitle("metamodelPanel", "Source Metamodel (Emfatic)");
+            setPanelTitle("secondModelPanel", "Target Model");
+            setPanelTitle("secondMetamodelPanel", "Target Metamodel (Emfatic)");
+
+        }
+        else if (language == "evl" || language == "epl") {
+            toggle("secondModelSplitter");
+            if (language == "evl") {
+                setPanelTitle("programPanel", "Constraints");
+                setPanelTitle("thirdModelPanel", "Errors/Warnings");
+            }
+            else {
+                setPanelTitle("programPanel", "Patterns");
+                setPanelTitle("thirdModelPanel", "Pattern Matches");
+            }
+        }
+        else if (language == "ecl") {
+            // Hide nothing; we need everything
+        }
+    }
+
+    function emptyButtons() {
+        return [];
+    }
+
+    function setPanelTitle(panelId, title) {
+        $("#" + panelId)[0].dataset.titleCaption = title;
+    }
+
     function editorsToJson() {
-        return JSON.stringify({"eol": eolEditor.getValue(), "emfatic": emfaticEditor.getValue(), "flexmi": flexmiEditor.getValue()});
+        return JSON.stringify(
+            {
+                "language": language,
+                "program": programEditor.getValue(), 
+                "emfatic": emfaticEditor.getValue(), 
+                "flexmi": flexmiEditor.getValue(),
+                "secondEmfatic": secondEmfaticEditor.getValue(),
+                "secondFlexmi": secondFlexmiEditor.getValue()
+            }
+        );
+    }
+
+    function modelToJson(modelEditor, metamodelEditor) {
+        return JSON.stringify(
+            {
+                "flexmi": modelEditor.getValue(), 
+                "emfatic": metamodelEditor.getValue()
+            }
+        );
     }
 
     function fit() {
@@ -174,21 +315,23 @@
 
         var editorParentStyle = "flex-basis: calc(100% - 4px);";
 
-        document.getElementById("eolEditor").parentNode.style = editorParentStyle;
+        document.getElementById("programEditor").parentNode.style = editorParentStyle;
+        document.getElementById("console").parentNode.style = editorParentStyle;
+
         document.getElementById("flexmiEditor").parentNode.parentNode.style = editorParentStyle + ";padding:0px";
         document.getElementById("emfaticEditor").parentNode.parentNode.style = editorParentStyle + ";padding:0px";
-        document.getElementById("console").parentNode.style = editorParentStyle;
+        document.getElementById("secondFlexmiEditor").parentNode.parentNode.style = editorParentStyle + ";padding:0px";
+        document.getElementById("secondEmfaticEditor").parentNode.parentNode.style = editorParentStyle + ";padding:0px";
         
-        eolEditor.resize();
-        flexmiEditor.resize();
-        emfaticEditor.resize();
-        consoleEditor.resize();
+        editors.forEach(e => e.resize());
+
     }
 
-	function runEol() {
+	function runProgram() {
 		
         var xhr = new XMLHttpRequest();
-        var url = "https://europe-west2-epsilon-live-gcp.cloudfunctions.net/run-eol";
+        //var url = "https://europe-west2-epsilon-live-gcp.cloudfunctions.net/run-eol";
+        var url = "https://europe-west2-epsilon-live-gcp.cloudfunctions.net/run-epsilon";
         //var url = "http://localhost:8080";
         xhr.open("POST", url, true);
         xhr.setRequestHeader("Content-Type", "application/json");
@@ -197,6 +340,13 @@
                 if (xhr.status === 200) {
                     var json = JSON.parse(xhr.responseText);
                     consoleEditor.setValue(json.output, 1);
+                    
+                    if (language == "etl") {
+                        console.log(json.targetModelDiagram);
+                        renderDiagram("secondModelDiagram", json.targetModelDiagram, 'dot');
+                    }
+
+                    
                 }
                 Metro.notify.killAll();
             }
@@ -208,12 +358,22 @@
 
     function refreshModelDiagram() {
         refreshDiagram("https://europe-west2-epsilon-live-gcp.cloudfunctions.net/flexmi-to-graphviz",
-            "modelDiagram", "model", "dot");
+            "modelDiagram", "model", "dot", flexmiEditor, emfaticEditor);
     }
 
     function refreshMetamodelDiagram() {
         refreshDiagram("https://europe-west2-epsilon-live-gcp.cloudfunctions.net/emfatic-to-graphviz",
-            "metamodelDiagram", "metamodel", "fdp");
+            "metamodelDiagram", "metamodel", "fdp", flexmiEditor, emfaticEditor);
+    }
+
+    function refreshSecondModelDiagram() {
+        refreshDiagram("https://europe-west2-epsilon-live-gcp.cloudfunctions.net/flexmi-to-graphviz",
+            "secondModelDiagram", "model", "dot", secondFlexmiEditor, secondEmfaticEditor);
+    }
+
+    function refreshSecondMetamodelDiagram() {
+        refreshDiagram("https://europe-west2-epsilon-live-gcp.cloudfunctions.net/emfatic-to-graphviz",
+            "secondMetamodelDiagram", "metamodel", "fdp", secondFlexmiEditor, secondEmfaticEditor);
     }
 
     function toggle(elementId, onEmpty) {
@@ -227,7 +387,7 @@
         else element.style.display = "none";
     }
 
-    function refreshDiagram(url, diagramId, diagramName, engine) {
+    function refreshDiagram(url, diagramId, diagramName, engine, modelEditor, metamodelEditor) {
         var xhr = new XMLHttpRequest();
         xhr.open("POST", url, true);
         xhr.setRequestHeader("Content-Type", "application/json");
@@ -237,19 +397,30 @@
                     var json = JSON.parse(xhr.responseText);
                     var t = d3.transition()
                         .ease(d3.easeLinear);
-                    d3.select("#" + diagramId).graphviz({fit: true, height: "100%", width:"100%", engine: engine})
-                        .transition(t)
-                        .renderDot(json[diagramId]);
+
+                    // FIXME: Make both functions return the Graphviz diagram in a "diagram" field
+                    var jsonField = "modelDiagram";
+                    if (diagramId.endsWith("etamodelDiagram")) jsonField = "metamodelDiagram";
+                    
+                    renderDiagram(diagramId, json[jsonField], engine);
+
                     Metro.notify.killAll();
                 }
             }
         };
-        var data = editorsToJson();
+        var data = modelToJson(modelEditor, metamodelEditor);
         xhr.send(data);
 
         Metro.notify.create("Rendering " + diagramName + " diagram...", null, {keepOpen: true, cls: "yellow"});
     }
 
+    function renderDiagram(diagramId, graphviz, engine) {
+        var t = d3.transition().ease(d3.easeLinear);
+        d3.select("#" + diagramId).graphviz({fit: true, height: "100%", width:"100%", engine: engine})
+            .transition(t)
+            .renderDot(graphviz);
+    }
+
     </script>
 </body>
 
diff --git a/sitemap.xml b/sitemap.xml
index 8191e09..ed6e7e1 100644
--- a/sitemap.xml
+++ b/sitemap.xml
@@ -1,123 +1,123 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-11-09</lastmod>
+     <lastmod>2020-11-12</lastmod>
      <changefreq>daily</changefreq>
     </url>
 </urlset>
\ No newline at end of file
diff --git a/sitemap.xml.gz b/sitemap.xml.gz
index 87a46ac..cd19d9c 100644
--- a/sitemap.xml.gz
+++ b/sitemap.xml.gz
Binary files differ
diff --git a/users/evidence/codebots-com-nov-11-2020.png b/users/evidence/codebots-com-nov-11-2020.png
new file mode 100644
index 0000000..860cea3
--- /dev/null
+++ b/users/evidence/codebots-com-nov-11-2020.png
Binary files differ