From 0aa08315d170dbf930d663b80acfaf794c9a32da Mon Sep 17 00:00:00 2001 From: Christian Klein Date: Sat, 26 Dec 2020 20:00:56 +0100 Subject: [PATCH] Added ability to load example from server --- elm.json | 3 + out/css/colors-light.css | 4 + out/css/style.css | 60 ++ out/elm.js | 1522 ++++++++++++++++++++++++++++++++++---- src/Main.elm | 201 ++++- 5 files changed, 1630 insertions(+), 160 deletions(-) diff --git a/elm.json b/elm.json index 2d0d191..1eb43b4 100644 --- a/elm.json +++ b/elm.json @@ -9,9 +9,12 @@ "elm/browser": "1.0.2", "elm/core": "1.0.5", "elm/html": "1.0.0", + "elm/http": "2.0.0", "elm/json": "1.1.3" }, "indirect": { + "elm/bytes": "1.0.8", + "elm/file": "1.0.5", "elm/time": "1.0.0", "elm/url": "1.0.0", "elm/virtual-dom": "1.0.2" diff --git a/out/css/colors-light.css b/out/css/colors-light.css index 6726e50..4a4d0ca 100644 --- a/out/css/colors-light.css +++ b/out/css/colors-light.css @@ -89,6 +89,10 @@ --color-arrow-text: var(--color-white); --color-arrow-text-hover: var(--color-white-light2); --color-arrow-border: var(--color-black-light1); + + --color-modal: var(--color-white-light1); + --color-modal-text: var(--color-black); + --color-modal-shadow: rgba( 0,0,0, 0.4 ); } diff --git a/out/css/style.css b/out/css/style.css index 370e665..c4d42f6 100644 --- a/out/css/style.css +++ b/out/css/style.css @@ -162,6 +162,10 @@ button { margin-bottom: -1em; } +.pc .scroller table { + margin: 0; +} + .pc .scroller table thead.head { position: sticky; top: -2px; @@ -508,6 +512,62 @@ th.address { } +/* MODALS */ +.modal { + position: fixed; + top: 0; + left: 0; + z-index: 1000; + + box-sizing: border-box; + width: 100vw; + height: 100vh; + + display: flex; + align-items: center; + justify-content: center; +} +.modal.hidden { + display: none; +} + +.modal-card { + z-index: 1500; + display: block; + width: 40em; + min-width: 45vw; + min-height: 5em; + position: relative; + box-sizing: border-box; + + padding: 2.5em 2em 1em 2em; + + background-color: var(--color-modal); + color: var(--color-modal-text); +} + +.modal > :first-child { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + + background-color: var(--color-modal-shadow); +} + +.modal .modal-close { + position: absolute; + top: .5em; + right: .5em; + +} + +.modal .modal-close::before { + content: "❌"; +} + + /* HELPERS */ .text-center { diff --git a/out/elm.js b/out/elm.js index 82fa75a..2401ca9 100644 --- a/out/elm.js +++ b/out/elm.js @@ -4355,7 +4355,182 @@ function _Browser_load(url) } })); } -var $elm$core$Basics$EQ = {$: 'EQ'}; + + + +// SEND REQUEST + +var _Http_toTask = F3(function(router, toTask, request) +{ + return _Scheduler_binding(function(callback) + { + function done(response) { + callback(toTask(request.expect.a(response))); + } + + var xhr = new XMLHttpRequest(); + xhr.addEventListener('error', function() { done($elm$http$Http$NetworkError_); }); + xhr.addEventListener('timeout', function() { done($elm$http$Http$Timeout_); }); + xhr.addEventListener('load', function() { done(_Http_toResponse(request.expect.b, xhr)); }); + $elm$core$Maybe$isJust(request.tracker) && _Http_track(router, xhr, request.tracker.a); + + try { + xhr.open(request.method, request.url, true); + } catch (e) { + return done($elm$http$Http$BadUrl_(request.url)); + } + + _Http_configureRequest(xhr, request); + + request.body.a && xhr.setRequestHeader('Content-Type', request.body.a); + xhr.send(request.body.b); + + return function() { xhr.c = true; xhr.abort(); }; + }); +}); + + +// CONFIGURE + +function _Http_configureRequest(xhr, request) +{ + for (var headers = request.headers; headers.b; headers = headers.b) // WHILE_CONS + { + xhr.setRequestHeader(headers.a.a, headers.a.b); + } + xhr.timeout = request.timeout.a || 0; + xhr.responseType = request.expect.d; + xhr.withCredentials = request.allowCookiesFromOtherDomains; +} + + +// RESPONSES + +function _Http_toResponse(toBody, xhr) +{ + return A2( + 200 <= xhr.status && xhr.status < 300 ? $elm$http$Http$GoodStatus_ : $elm$http$Http$BadStatus_, + _Http_toMetadata(xhr), + toBody(xhr.response) + ); +} + + +// METADATA + +function _Http_toMetadata(xhr) +{ + return { + url: xhr.responseURL, + statusCode: xhr.status, + statusText: xhr.statusText, + headers: _Http_parseHeaders(xhr.getAllResponseHeaders()) + }; +} + + +// HEADERS + +function _Http_parseHeaders(rawHeaders) +{ + if (!rawHeaders) + { + return $elm$core$Dict$empty; + } + + var headers = $elm$core$Dict$empty; + var headerPairs = rawHeaders.split('\r\n'); + for (var i = headerPairs.length; i--; ) + { + var headerPair = headerPairs[i]; + var index = headerPair.indexOf(': '); + if (index > 0) + { + var key = headerPair.substring(0, index); + var value = headerPair.substring(index + 2); + + headers = A3($elm$core$Dict$update, key, function(oldValue) { + return $elm$core$Maybe$Just($elm$core$Maybe$isJust(oldValue) + ? value + ', ' + oldValue.a + : value + ); + }, headers); + } + } + return headers; +} + + +// EXPECT + +var _Http_expect = F3(function(type, toBody, toValue) +{ + return { + $: 0, + d: type, + b: toBody, + a: toValue + }; +}); + +var _Http_mapExpect = F2(function(func, expect) +{ + return { + $: 0, + d: expect.d, + b: expect.b, + a: function(x) { return func(expect.a(x)); } + }; +}); + +function _Http_toDataView(arrayBuffer) +{ + return new DataView(arrayBuffer); +} + + +// BODY and PARTS + +var _Http_emptyBody = { $: 0 }; +var _Http_pair = F2(function(a, b) { return { $: 0, a: a, b: b }; }); + +function _Http_toFormData(parts) +{ + for (var formData = new FormData(); parts.b; parts = parts.b) // WHILE_CONS + { + var part = parts.a; + formData.append(part.a, part.b); + } + return formData; +} + +var _Http_bytesToBlob = F2(function(mime, bytes) +{ + return new Blob([bytes], { type: mime }); +}); + + +// PROGRESS + +function _Http_track(router, xhr, tracker) +{ + // TODO check out lengthComputable on loadstart event + + xhr.upload.addEventListener('progress', function(event) { + if (xhr.c) { return; } + _Scheduler_rawSpawn(A2($elm$core$Platform$sendToSelf, router, _Utils_Tuple2(tracker, $elm$http$Http$Sending({ + sent: event.loaded, + size: event.total + })))); + }); + xhr.addEventListener('progress', function(event) { + if (xhr.c) { return; } + _Scheduler_rawSpawn(A2($elm$core$Platform$sendToSelf, router, _Utils_Tuple2(tracker, $elm$http$Http$Receiving({ + received: event.loaded, + size: event.lengthComputable ? $elm$core$Maybe$Just(event.total) : $elm$core$Maybe$Nothing + })))); + }); +}var $elm$core$Basics$EQ = {$: 'EQ'}; var $elm$core$Basics$GT = {$: 'GT'}; var $elm$core$Basics$LT = {$: 'LT'}; var $elm$core$List$cons = _List_cons; @@ -5144,10 +5319,11 @@ var $elm$core$Task$perform = F2( A2($elm$core$Task$map, toMessage, task))); }); var $elm$browser$Browser$element = _Browser_element; -var $author$project$Main$Model = F3( - function (pc, uCode, autoscroll) { - return {autoscroll: autoscroll, pc: pc, uCode: uCode}; +var $author$project$Main$Model = F7( + function (pc, uCode, autoscroll, examples, exampleChooserOpen, examplesListStatus, exampleLoaderStatus) { + return {autoscroll: autoscroll, exampleChooserOpen: exampleChooserOpen, exampleLoaderStatus: exampleLoaderStatus, examples: examples, examplesListStatus: examplesListStatus, pc: pc, uCode: uCode}; }); +var $author$project$Main$Waiting = {$: 'Waiting'}; var $author$project$Main$PC = F7( function (ram, dataBus, addressBus, instructionReg, programmCounter, uCounter, accumulator) { return {accumulator: accumulator, addressBus: addressBus, dataBus: dataBus, instructionReg: instructionReg, programmCounter: programmCounter, ram: ram, uCounter: uCounter}; @@ -5174,7 +5350,7 @@ var $elm$core$Platform$Cmd$batch = _Platform_batch; var $elm$core$Platform$Cmd$none = $elm$core$Platform$Cmd$batch(_List_Nil); var $author$project$Main$init = function (flags) { return _Utils_Tuple2( - A3($author$project$Main$Model, $author$project$Main$initialPC, $author$project$Main$initialUCodes, true), + A7($author$project$Main$Model, $author$project$Main$initialPC, $author$project$Main$initialUCodes, true, _List_Nil, false, $author$project$Main$Waiting, $author$project$Main$Waiting), $elm$core$Platform$Cmd$none); }; var $author$project$Main$MsgLocalSessionRecieve = function (a) { @@ -5185,6 +5361,10 @@ var $author$project$Main$localStorageRecieve = _Platform_incomingPort('localStor var $author$project$Main$subscriptions = function (model) { return $author$project$Main$localStorageRecieve($author$project$Main$MsgLocalSessionRecieve); }; +var $author$project$Main$Failure = function (a) { + return {$: 'Failure', a: a}; +}; +var $author$project$Main$Success = {$: 'Success'}; var $elm$core$List$append = F2( function (xs, ys) { if (!ys.b) { @@ -5390,6 +5570,948 @@ var $author$project$Main$changeAtUCode = F3( function (pos, newVal, list) { return A4($author$project$Main$changeAt, pos, newVal, $author$project$Main$ActNothing, list); }); +var $author$project$Main$MsgLoadExampleArrived = function (a) { + return {$: 'MsgLoadExampleArrived', a: a}; +}; +var $elm$json$Json$Decode$decodeString = _Json_runOnString; +var $elm$http$Http$BadStatus_ = F2( + function (a, b) { + return {$: 'BadStatus_', a: a, b: b}; + }); +var $elm$http$Http$BadUrl_ = function (a) { + return {$: 'BadUrl_', a: a}; +}; +var $elm$http$Http$GoodStatus_ = F2( + function (a, b) { + return {$: 'GoodStatus_', a: a, b: b}; + }); +var $elm$http$Http$NetworkError_ = {$: 'NetworkError_'}; +var $elm$http$Http$Receiving = function (a) { + return {$: 'Receiving', a: a}; +}; +var $elm$http$Http$Sending = function (a) { + return {$: 'Sending', a: a}; +}; +var $elm$http$Http$Timeout_ = {$: 'Timeout_'}; +var $elm$core$Dict$RBEmpty_elm_builtin = {$: 'RBEmpty_elm_builtin'}; +var $elm$core$Dict$empty = $elm$core$Dict$RBEmpty_elm_builtin; +var $elm$core$Maybe$isJust = function (maybe) { + if (maybe.$ === 'Just') { + return true; + } else { + return false; + } +}; +var $elm$core$Platform$sendToSelf = _Platform_sendToSelf; +var $elm$core$Basics$compare = _Utils_compare; +var $elm$core$Dict$get = F2( + function (targetKey, dict) { + get: + while (true) { + if (dict.$ === 'RBEmpty_elm_builtin') { + return $elm$core$Maybe$Nothing; + } else { + var key = dict.b; + var value = dict.c; + var left = dict.d; + var right = dict.e; + var _v1 = A2($elm$core$Basics$compare, targetKey, key); + switch (_v1.$) { + case 'LT': + var $temp$targetKey = targetKey, + $temp$dict = left; + targetKey = $temp$targetKey; + dict = $temp$dict; + continue get; + case 'EQ': + return $elm$core$Maybe$Just(value); + default: + var $temp$targetKey = targetKey, + $temp$dict = right; + targetKey = $temp$targetKey; + dict = $temp$dict; + continue get; + } + } + } + }); +var $elm$core$Dict$Black = {$: 'Black'}; +var $elm$core$Dict$RBNode_elm_builtin = F5( + function (a, b, c, d, e) { + return {$: 'RBNode_elm_builtin', a: a, b: b, c: c, d: d, e: e}; + }); +var $elm$core$Dict$Red = {$: 'Red'}; +var $elm$core$Dict$balance = F5( + function (color, key, value, left, right) { + if ((right.$ === 'RBNode_elm_builtin') && (right.a.$ === 'Red')) { + var _v1 = right.a; + var rK = right.b; + var rV = right.c; + var rLeft = right.d; + var rRight = right.e; + if ((left.$ === 'RBNode_elm_builtin') && (left.a.$ === 'Red')) { + var _v3 = left.a; + var lK = left.b; + var lV = left.c; + var lLeft = left.d; + var lRight = left.e; + return A5( + $elm$core$Dict$RBNode_elm_builtin, + $elm$core$Dict$Red, + key, + value, + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Black, lK, lV, lLeft, lRight), + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Black, rK, rV, rLeft, rRight)); + } else { + return A5( + $elm$core$Dict$RBNode_elm_builtin, + color, + rK, + rV, + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Red, key, value, left, rLeft), + rRight); + } + } else { + if ((((left.$ === 'RBNode_elm_builtin') && (left.a.$ === 'Red')) && (left.d.$ === 'RBNode_elm_builtin')) && (left.d.a.$ === 'Red')) { + var _v5 = left.a; + var lK = left.b; + var lV = left.c; + var _v6 = left.d; + var _v7 = _v6.a; + var llK = _v6.b; + var llV = _v6.c; + var llLeft = _v6.d; + var llRight = _v6.e; + var lRight = left.e; + return A5( + $elm$core$Dict$RBNode_elm_builtin, + $elm$core$Dict$Red, + lK, + lV, + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Black, llK, llV, llLeft, llRight), + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Black, key, value, lRight, right)); + } else { + return A5($elm$core$Dict$RBNode_elm_builtin, color, key, value, left, right); + } + } + }); +var $elm$core$Dict$insertHelp = F3( + function (key, value, dict) { + if (dict.$ === 'RBEmpty_elm_builtin') { + return A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Red, key, value, $elm$core$Dict$RBEmpty_elm_builtin, $elm$core$Dict$RBEmpty_elm_builtin); + } else { + var nColor = dict.a; + var nKey = dict.b; + var nValue = dict.c; + var nLeft = dict.d; + var nRight = dict.e; + var _v1 = A2($elm$core$Basics$compare, key, nKey); + switch (_v1.$) { + case 'LT': + return A5( + $elm$core$Dict$balance, + nColor, + nKey, + nValue, + A3($elm$core$Dict$insertHelp, key, value, nLeft), + nRight); + case 'EQ': + return A5($elm$core$Dict$RBNode_elm_builtin, nColor, nKey, value, nLeft, nRight); + default: + return A5( + $elm$core$Dict$balance, + nColor, + nKey, + nValue, + nLeft, + A3($elm$core$Dict$insertHelp, key, value, nRight)); + } + } + }); +var $elm$core$Dict$insert = F3( + function (key, value, dict) { + var _v0 = A3($elm$core$Dict$insertHelp, key, value, dict); + if ((_v0.$ === 'RBNode_elm_builtin') && (_v0.a.$ === 'Red')) { + var _v1 = _v0.a; + var k = _v0.b; + var v = _v0.c; + var l = _v0.d; + var r = _v0.e; + return A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Black, k, v, l, r); + } else { + var x = _v0; + return x; + } + }); +var $elm$core$Dict$getMin = function (dict) { + getMin: + while (true) { + if ((dict.$ === 'RBNode_elm_builtin') && (dict.d.$ === 'RBNode_elm_builtin')) { + var left = dict.d; + var $temp$dict = left; + dict = $temp$dict; + continue getMin; + } else { + return dict; + } + } +}; +var $elm$core$Dict$moveRedLeft = function (dict) { + if (((dict.$ === 'RBNode_elm_builtin') && (dict.d.$ === 'RBNode_elm_builtin')) && (dict.e.$ === 'RBNode_elm_builtin')) { + if ((dict.e.d.$ === 'RBNode_elm_builtin') && (dict.e.d.a.$ === 'Red')) { + var clr = dict.a; + var k = dict.b; + var v = dict.c; + var _v1 = dict.d; + var lClr = _v1.a; + var lK = _v1.b; + var lV = _v1.c; + var lLeft = _v1.d; + var lRight = _v1.e; + var _v2 = dict.e; + var rClr = _v2.a; + var rK = _v2.b; + var rV = _v2.c; + var rLeft = _v2.d; + var _v3 = rLeft.a; + var rlK = rLeft.b; + var rlV = rLeft.c; + var rlL = rLeft.d; + var rlR = rLeft.e; + var rRight = _v2.e; + return A5( + $elm$core$Dict$RBNode_elm_builtin, + $elm$core$Dict$Red, + rlK, + rlV, + A5( + $elm$core$Dict$RBNode_elm_builtin, + $elm$core$Dict$Black, + k, + v, + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Red, lK, lV, lLeft, lRight), + rlL), + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Black, rK, rV, rlR, rRight)); + } else { + var clr = dict.a; + var k = dict.b; + var v = dict.c; + var _v4 = dict.d; + var lClr = _v4.a; + var lK = _v4.b; + var lV = _v4.c; + var lLeft = _v4.d; + var lRight = _v4.e; + var _v5 = dict.e; + var rClr = _v5.a; + var rK = _v5.b; + var rV = _v5.c; + var rLeft = _v5.d; + var rRight = _v5.e; + if (clr.$ === 'Black') { + return A5( + $elm$core$Dict$RBNode_elm_builtin, + $elm$core$Dict$Black, + k, + v, + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Red, lK, lV, lLeft, lRight), + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Red, rK, rV, rLeft, rRight)); + } else { + return A5( + $elm$core$Dict$RBNode_elm_builtin, + $elm$core$Dict$Black, + k, + v, + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Red, lK, lV, lLeft, lRight), + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Red, rK, rV, rLeft, rRight)); + } + } + } else { + return dict; + } +}; +var $elm$core$Dict$moveRedRight = function (dict) { + if (((dict.$ === 'RBNode_elm_builtin') && (dict.d.$ === 'RBNode_elm_builtin')) && (dict.e.$ === 'RBNode_elm_builtin')) { + if ((dict.d.d.$ === 'RBNode_elm_builtin') && (dict.d.d.a.$ === 'Red')) { + var clr = dict.a; + var k = dict.b; + var v = dict.c; + var _v1 = dict.d; + var lClr = _v1.a; + var lK = _v1.b; + var lV = _v1.c; + var _v2 = _v1.d; + var _v3 = _v2.a; + var llK = _v2.b; + var llV = _v2.c; + var llLeft = _v2.d; + var llRight = _v2.e; + var lRight = _v1.e; + var _v4 = dict.e; + var rClr = _v4.a; + var rK = _v4.b; + var rV = _v4.c; + var rLeft = _v4.d; + var rRight = _v4.e; + return A5( + $elm$core$Dict$RBNode_elm_builtin, + $elm$core$Dict$Red, + lK, + lV, + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Black, llK, llV, llLeft, llRight), + A5( + $elm$core$Dict$RBNode_elm_builtin, + $elm$core$Dict$Black, + k, + v, + lRight, + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Red, rK, rV, rLeft, rRight))); + } else { + var clr = dict.a; + var k = dict.b; + var v = dict.c; + var _v5 = dict.d; + var lClr = _v5.a; + var lK = _v5.b; + var lV = _v5.c; + var lLeft = _v5.d; + var lRight = _v5.e; + var _v6 = dict.e; + var rClr = _v6.a; + var rK = _v6.b; + var rV = _v6.c; + var rLeft = _v6.d; + var rRight = _v6.e; + if (clr.$ === 'Black') { + return A5( + $elm$core$Dict$RBNode_elm_builtin, + $elm$core$Dict$Black, + k, + v, + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Red, lK, lV, lLeft, lRight), + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Red, rK, rV, rLeft, rRight)); + } else { + return A5( + $elm$core$Dict$RBNode_elm_builtin, + $elm$core$Dict$Black, + k, + v, + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Red, lK, lV, lLeft, lRight), + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Red, rK, rV, rLeft, rRight)); + } + } + } else { + return dict; + } +}; +var $elm$core$Dict$removeHelpPrepEQGT = F7( + function (targetKey, dict, color, key, value, left, right) { + if ((left.$ === 'RBNode_elm_builtin') && (left.a.$ === 'Red')) { + var _v1 = left.a; + var lK = left.b; + var lV = left.c; + var lLeft = left.d; + var lRight = left.e; + return A5( + $elm$core$Dict$RBNode_elm_builtin, + color, + lK, + lV, + lLeft, + A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Red, key, value, lRight, right)); + } else { + _v2$2: + while (true) { + if ((right.$ === 'RBNode_elm_builtin') && (right.a.$ === 'Black')) { + if (right.d.$ === 'RBNode_elm_builtin') { + if (right.d.a.$ === 'Black') { + var _v3 = right.a; + var _v4 = right.d; + var _v5 = _v4.a; + return $elm$core$Dict$moveRedRight(dict); + } else { + break _v2$2; + } + } else { + var _v6 = right.a; + var _v7 = right.d; + return $elm$core$Dict$moveRedRight(dict); + } + } else { + break _v2$2; + } + } + return dict; + } + }); +var $elm$core$Dict$removeMin = function (dict) { + if ((dict.$ === 'RBNode_elm_builtin') && (dict.d.$ === 'RBNode_elm_builtin')) { + var color = dict.a; + var key = dict.b; + var value = dict.c; + var left = dict.d; + var lColor = left.a; + var lLeft = left.d; + var right = dict.e; + if (lColor.$ === 'Black') { + if ((lLeft.$ === 'RBNode_elm_builtin') && (lLeft.a.$ === 'Red')) { + var _v3 = lLeft.a; + return A5( + $elm$core$Dict$RBNode_elm_builtin, + color, + key, + value, + $elm$core$Dict$removeMin(left), + right); + } else { + var _v4 = $elm$core$Dict$moveRedLeft(dict); + if (_v4.$ === 'RBNode_elm_builtin') { + var nColor = _v4.a; + var nKey = _v4.b; + var nValue = _v4.c; + var nLeft = _v4.d; + var nRight = _v4.e; + return A5( + $elm$core$Dict$balance, + nColor, + nKey, + nValue, + $elm$core$Dict$removeMin(nLeft), + nRight); + } else { + return $elm$core$Dict$RBEmpty_elm_builtin; + } + } + } else { + return A5( + $elm$core$Dict$RBNode_elm_builtin, + color, + key, + value, + $elm$core$Dict$removeMin(left), + right); + } + } else { + return $elm$core$Dict$RBEmpty_elm_builtin; + } +}; +var $elm$core$Dict$removeHelp = F2( + function (targetKey, dict) { + if (dict.$ === 'RBEmpty_elm_builtin') { + return $elm$core$Dict$RBEmpty_elm_builtin; + } else { + var color = dict.a; + var key = dict.b; + var value = dict.c; + var left = dict.d; + var right = dict.e; + if (_Utils_cmp(targetKey, key) < 0) { + if ((left.$ === 'RBNode_elm_builtin') && (left.a.$ === 'Black')) { + var _v4 = left.a; + var lLeft = left.d; + if ((lLeft.$ === 'RBNode_elm_builtin') && (lLeft.a.$ === 'Red')) { + var _v6 = lLeft.a; + return A5( + $elm$core$Dict$RBNode_elm_builtin, + color, + key, + value, + A2($elm$core$Dict$removeHelp, targetKey, left), + right); + } else { + var _v7 = $elm$core$Dict$moveRedLeft(dict); + if (_v7.$ === 'RBNode_elm_builtin') { + var nColor = _v7.a; + var nKey = _v7.b; + var nValue = _v7.c; + var nLeft = _v7.d; + var nRight = _v7.e; + return A5( + $elm$core$Dict$balance, + nColor, + nKey, + nValue, + A2($elm$core$Dict$removeHelp, targetKey, nLeft), + nRight); + } else { + return $elm$core$Dict$RBEmpty_elm_builtin; + } + } + } else { + return A5( + $elm$core$Dict$RBNode_elm_builtin, + color, + key, + value, + A2($elm$core$Dict$removeHelp, targetKey, left), + right); + } + } else { + return A2( + $elm$core$Dict$removeHelpEQGT, + targetKey, + A7($elm$core$Dict$removeHelpPrepEQGT, targetKey, dict, color, key, value, left, right)); + } + } + }); +var $elm$core$Dict$removeHelpEQGT = F2( + function (targetKey, dict) { + if (dict.$ === 'RBNode_elm_builtin') { + var color = dict.a; + var key = dict.b; + var value = dict.c; + var left = dict.d; + var right = dict.e; + if (_Utils_eq(targetKey, key)) { + var _v1 = $elm$core$Dict$getMin(right); + if (_v1.$ === 'RBNode_elm_builtin') { + var minKey = _v1.b; + var minValue = _v1.c; + return A5( + $elm$core$Dict$balance, + color, + minKey, + minValue, + left, + $elm$core$Dict$removeMin(right)); + } else { + return $elm$core$Dict$RBEmpty_elm_builtin; + } + } else { + return A5( + $elm$core$Dict$balance, + color, + key, + value, + left, + A2($elm$core$Dict$removeHelp, targetKey, right)); + } + } else { + return $elm$core$Dict$RBEmpty_elm_builtin; + } + }); +var $elm$core$Dict$remove = F2( + function (key, dict) { + var _v0 = A2($elm$core$Dict$removeHelp, key, dict); + if ((_v0.$ === 'RBNode_elm_builtin') && (_v0.a.$ === 'Red')) { + var _v1 = _v0.a; + var k = _v0.b; + var v = _v0.c; + var l = _v0.d; + var r = _v0.e; + return A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Black, k, v, l, r); + } else { + var x = _v0; + return x; + } + }); +var $elm$core$Dict$update = F3( + function (targetKey, alter, dictionary) { + var _v0 = alter( + A2($elm$core$Dict$get, targetKey, dictionary)); + if (_v0.$ === 'Just') { + var value = _v0.a; + return A3($elm$core$Dict$insert, targetKey, value, dictionary); + } else { + return A2($elm$core$Dict$remove, targetKey, dictionary); + } + }); +var $elm$core$Basics$composeR = F3( + function (f, g, x) { + return g( + f(x)); + }); +var $elm$http$Http$expectStringResponse = F2( + function (toMsg, toResult) { + return A3( + _Http_expect, + '', + $elm$core$Basics$identity, + A2($elm$core$Basics$composeR, toResult, toMsg)); + }); +var $elm$core$Result$mapError = F2( + function (f, result) { + if (result.$ === 'Ok') { + var v = result.a; + return $elm$core$Result$Ok(v); + } else { + var e = result.a; + return $elm$core$Result$Err( + f(e)); + } + }); +var $elm$http$Http$BadBody = function (a) { + return {$: 'BadBody', a: a}; +}; +var $elm$http$Http$BadStatus = function (a) { + return {$: 'BadStatus', a: a}; +}; +var $elm$http$Http$BadUrl = function (a) { + return {$: 'BadUrl', a: a}; +}; +var $elm$http$Http$NetworkError = {$: 'NetworkError'}; +var $elm$http$Http$Timeout = {$: 'Timeout'}; +var $elm$http$Http$resolve = F2( + function (toResult, response) { + switch (response.$) { + case 'BadUrl_': + var url = response.a; + return $elm$core$Result$Err( + $elm$http$Http$BadUrl(url)); + case 'Timeout_': + return $elm$core$Result$Err($elm$http$Http$Timeout); + case 'NetworkError_': + return $elm$core$Result$Err($elm$http$Http$NetworkError); + case 'BadStatus_': + var metadata = response.a; + return $elm$core$Result$Err( + $elm$http$Http$BadStatus(metadata.statusCode)); + default: + var body = response.b; + return A2( + $elm$core$Result$mapError, + $elm$http$Http$BadBody, + toResult(body)); + } + }); +var $elm$http$Http$expectJson = F2( + function (toMsg, decoder) { + return A2( + $elm$http$Http$expectStringResponse, + toMsg, + $elm$http$Http$resolve( + function (string) { + return A2( + $elm$core$Result$mapError, + $elm$json$Json$Decode$errorToString, + A2($elm$json$Json$Decode$decodeString, decoder, string)); + })); + }); +var $elm$http$Http$emptyBody = _Http_emptyBody; +var $elm$http$Http$Request = function (a) { + return {$: 'Request', a: a}; +}; +var $elm$http$Http$State = F2( + function (reqs, subs) { + return {reqs: reqs, subs: subs}; + }); +var $elm$http$Http$init = $elm$core$Task$succeed( + A2($elm$http$Http$State, $elm$core$Dict$empty, _List_Nil)); +var $elm$core$Process$kill = _Scheduler_kill; +var $elm$core$Process$spawn = _Scheduler_spawn; +var $elm$http$Http$updateReqs = F3( + function (router, cmds, reqs) { + updateReqs: + while (true) { + if (!cmds.b) { + return $elm$core$Task$succeed(reqs); + } else { + var cmd = cmds.a; + var otherCmds = cmds.b; + if (cmd.$ === 'Cancel') { + var tracker = cmd.a; + var _v2 = A2($elm$core$Dict$get, tracker, reqs); + if (_v2.$ === 'Nothing') { + var $temp$router = router, + $temp$cmds = otherCmds, + $temp$reqs = reqs; + router = $temp$router; + cmds = $temp$cmds; + reqs = $temp$reqs; + continue updateReqs; + } else { + var pid = _v2.a; + return A2( + $elm$core$Task$andThen, + function (_v3) { + return A3( + $elm$http$Http$updateReqs, + router, + otherCmds, + A2($elm$core$Dict$remove, tracker, reqs)); + }, + $elm$core$Process$kill(pid)); + } + } else { + var req = cmd.a; + return A2( + $elm$core$Task$andThen, + function (pid) { + var _v4 = req.tracker; + if (_v4.$ === 'Nothing') { + return A3($elm$http$Http$updateReqs, router, otherCmds, reqs); + } else { + var tracker = _v4.a; + return A3( + $elm$http$Http$updateReqs, + router, + otherCmds, + A3($elm$core$Dict$insert, tracker, pid, reqs)); + } + }, + $elm$core$Process$spawn( + A3( + _Http_toTask, + router, + $elm$core$Platform$sendToApp(router), + req))); + } + } + } + }); +var $elm$http$Http$onEffects = F4( + function (router, cmds, subs, state) { + return A2( + $elm$core$Task$andThen, + function (reqs) { + return $elm$core$Task$succeed( + A2($elm$http$Http$State, reqs, subs)); + }, + A3($elm$http$Http$updateReqs, router, cmds, state.reqs)); + }); +var $elm$core$List$maybeCons = F3( + function (f, mx, xs) { + var _v0 = f(mx); + if (_v0.$ === 'Just') { + var x = _v0.a; + return A2($elm$core$List$cons, x, xs); + } else { + return xs; + } + }); +var $elm$core$List$filterMap = F2( + function (f, xs) { + return A3( + $elm$core$List$foldr, + $elm$core$List$maybeCons(f), + _List_Nil, + xs); + }); +var $elm$http$Http$maybeSend = F4( + function (router, desiredTracker, progress, _v0) { + var actualTracker = _v0.a; + var toMsg = _v0.b; + return _Utils_eq(desiredTracker, actualTracker) ? $elm$core$Maybe$Just( + A2( + $elm$core$Platform$sendToApp, + router, + toMsg(progress))) : $elm$core$Maybe$Nothing; + }); +var $elm$http$Http$onSelfMsg = F3( + function (router, _v0, state) { + var tracker = _v0.a; + var progress = _v0.b; + return A2( + $elm$core$Task$andThen, + function (_v1) { + return $elm$core$Task$succeed(state); + }, + $elm$core$Task$sequence( + A2( + $elm$core$List$filterMap, + A3($elm$http$Http$maybeSend, router, tracker, progress), + state.subs))); + }); +var $elm$http$Http$Cancel = function (a) { + return {$: 'Cancel', a: a}; +}; +var $elm$http$Http$cmdMap = F2( + function (func, cmd) { + if (cmd.$ === 'Cancel') { + var tracker = cmd.a; + return $elm$http$Http$Cancel(tracker); + } else { + var r = cmd.a; + return $elm$http$Http$Request( + { + allowCookiesFromOtherDomains: r.allowCookiesFromOtherDomains, + body: r.body, + expect: A2(_Http_mapExpect, func, r.expect), + headers: r.headers, + method: r.method, + timeout: r.timeout, + tracker: r.tracker, + url: r.url + }); + } + }); +var $elm$http$Http$MySub = F2( + function (a, b) { + return {$: 'MySub', a: a, b: b}; + }); +var $elm$http$Http$subMap = F2( + function (func, _v0) { + var tracker = _v0.a; + var toMsg = _v0.b; + return A2( + $elm$http$Http$MySub, + tracker, + A2($elm$core$Basics$composeR, toMsg, func)); + }); +_Platform_effectManagers['Http'] = _Platform_createManager($elm$http$Http$init, $elm$http$Http$onEffects, $elm$http$Http$onSelfMsg, $elm$http$Http$cmdMap, $elm$http$Http$subMap); +var $elm$http$Http$command = _Platform_leaf('Http'); +var $elm$http$Http$subscription = _Platform_leaf('Http'); +var $elm$http$Http$request = function (r) { + return $elm$http$Http$command( + $elm$http$Http$Request( + {allowCookiesFromOtherDomains: false, body: r.body, expect: r.expect, headers: r.headers, method: r.method, timeout: r.timeout, tracker: r.tracker, url: r.url})); +}; +var $elm$http$Http$get = function (r) { + return $elm$http$Http$request( + {body: $elm$http$Http$emptyBody, expect: r.expect, headers: _List_Nil, method: 'GET', timeout: $elm$core$Maybe$Nothing, tracker: $elm$core$Maybe$Nothing, url: r.url}); +}; +var $elm$json$Json$Decode$bool = _Json_decodeBool; +var $elm$json$Json$Decode$field = _Json_decodeField; +var $elm$json$Json$Decode$int = _Json_decodeInt; +var $elm$json$Json$Decode$list = _Json_decodeList; +var $elm$json$Json$Decode$map3 = _Json_map3; +var $elm$json$Json$Decode$map7 = _Json_map7; +var $elm$core$List$filter = F2( + function (isGood, list) { + return A3( + $elm$core$List$foldr, + F2( + function (x, xs) { + return isGood(x) ? A2($elm$core$List$cons, x, xs) : xs; + }), + _List_Nil, + list); + }); +var $elm$core$List$head = function (list) { + if (list.b) { + var x = list.a; + var xs = list.b; + return $elm$core$Maybe$Just(x); + } else { + return $elm$core$Maybe$Nothing; + } +}; +var $elm$core$Tuple$second = function (_v0) { + var y = _v0.b; + return y; +}; +var $author$project$Main$ActAccumulatorDecrement = {$: 'ActAccumulatorDecrement'}; +var $author$project$Main$uCodeIds = _List_fromArray( + [ + _Utils_Tuple2($author$project$Main$ActAccumulator2DataBus, 'acc2db'), + _Utils_Tuple2($author$project$Main$ActAccumulatorDecrement, 'accDec'), + _Utils_Tuple2($author$project$Main$ActAccumulatorIncrement, 'accInc'), + _Utils_Tuple2($author$project$Main$ActDataBus2Accumulator, 'db2acc'), + _Utils_Tuple2($author$project$Main$ActDataBus2InstructionReg, 'db2ir'), + _Utils_Tuple2($author$project$Main$ActDataBus2Ram, 'db2ram'), + _Utils_Tuple2($author$project$Main$ActInstructionReg2AddressBus, 'ir2ab'), + _Utils_Tuple2($author$project$Main$ActInstructionReg2ProgrammCounter, 'ir2pc'), + _Utils_Tuple2($author$project$Main$ActInstructionReg2UCounter, 'ir2uc'), + _Utils_Tuple2($author$project$Main$ActProgrammCounterIncrement, 'pcInc'), + _Utils_Tuple2($author$project$Main$ActRam2DataBus, 'ram2db'), + _Utils_Tuple2($author$project$Main$ActResetUCounter, 'ucReset'), + _Utils_Tuple2($author$project$Main$ActProgrammCounter2AddressBus, 'pc2ab'), + _Utils_Tuple2($author$project$Main$ActNothing, 'n') + ]); +var $author$project$Main$string2uAction = function (msg) { + var filtered_list = A2( + $elm$core$List$filter, + function (s) { + return _Utils_eq(s.b, msg); + }, + $author$project$Main$uCodeIds); + var _v0 = $elm$core$List$head(filtered_list); + if (_v0.$ === 'Just') { + var _v1 = _v0.a; + var action = _v1.a; + return $elm$core$Maybe$Just(action); + } else { + return $elm$core$Maybe$Nothing; + } +}; +var $elm$core$Maybe$withDefault = F2( + function (_default, maybe) { + if (maybe.$ === 'Just') { + var value = maybe.a; + return value; + } else { + return _default; + } + }); +var $author$project$Main$modelDecoder = A4( + $elm$json$Json$Decode$map3, + F3( + function (a, b, c) { + return A7($author$project$Main$Model, a, b, c, _List_Nil, false, $author$project$Main$Waiting, $author$project$Main$Waiting); + }), + A2( + $elm$json$Json$Decode$field, + 'pc', + A8( + $elm$json$Json$Decode$map7, + $author$project$Main$PC, + A2( + $elm$json$Json$Decode$field, + 'ram', + $elm$json$Json$Decode$list($elm$json$Json$Decode$int)), + A2($elm$json$Json$Decode$field, 'dataBus', $elm$json$Json$Decode$int), + A2($elm$json$Json$Decode$field, 'addressBus', $elm$json$Json$Decode$int), + A2($elm$json$Json$Decode$field, 'instructionReg', $elm$json$Json$Decode$int), + A2($elm$json$Json$Decode$field, 'programmCounter', $elm$json$Json$Decode$int), + A2($elm$json$Json$Decode$field, 'uCounter', $elm$json$Json$Decode$int), + A2($elm$json$Json$Decode$field, 'accumulator', $elm$json$Json$Decode$int))), + A2( + $elm$json$Json$Decode$field, + 'uCode', + $elm$json$Json$Decode$list( + A2( + $elm$json$Json$Decode$map, + function (s) { + return A2( + $elm$core$Maybe$withDefault, + $author$project$Main$ActNothing, + $author$project$Main$string2uAction(s)); + }, + $elm$json$Json$Decode$string))), + A2($elm$json$Json$Decode$field, 'autoscroll', $elm$json$Json$Decode$bool)); +var $author$project$Main$cmdLoadExampleSing = F2( + function (model, example) { + return $elm$http$Http$get( + { + expect: A2($elm$http$Http$expectJson, $author$project$Main$MsgLoadExampleArrived, $author$project$Main$modelDecoder), + url: example.url + }); + }); +var $author$project$Main$MsgExamplesArrived = function (a) { + return {$: 'MsgExamplesArrived', a: a}; +}; +var $author$project$Main$Example = F4( + function (title, version, url, enabled) { + return {enabled: enabled, title: title, url: url, version: version}; + }); +var $elm$json$Json$Decode$map4 = _Json_map4; +var $author$project$Main$exampleListDecoder = A2( + $elm$json$Json$Decode$field, + 'available', + $elm$json$Json$Decode$list( + A5( + $elm$json$Json$Decode$map4, + $author$project$Main$Example, + A2($elm$json$Json$Decode$field, 'title', $elm$json$Json$Decode$string), + A2($elm$json$Json$Decode$field, 'version', $elm$json$Json$Decode$string), + A2($elm$json$Json$Decode$field, 'url', $elm$json$Json$Decode$string), + A2( + $elm$json$Json$Decode$field, + 'enabled', + A2( + $elm$json$Json$Decode$map, + function (s) { + return s === 1; + }, + $elm$json$Json$Decode$int))))); +var $author$project$Main$examplesListUrl = 'examples-list.json'; +var $author$project$Main$cmdLoadExamples = function (model) { + return $elm$http$Http$get( + { + expect: A2($elm$http$Http$expectJson, $author$project$Main$MsgExamplesArrived, $author$project$Main$exampleListDecoder), + url: $author$project$Main$examplesListUrl + }); +}; var $elm$json$Json$Encode$bool = _Json_wrap; var $elm$json$Json$Encode$int = _Json_wrap; var $elm$json$Json$Encode$list = F2( @@ -5416,44 +6538,6 @@ var $elm$json$Json$Encode$object = function (pairs) { pairs)); }; var $elm$json$Json$Encode$string = _Json_wrap; -var $elm$core$List$filter = F2( - function (isGood, list) { - return A3( - $elm$core$List$foldr, - F2( - function (x, xs) { - return isGood(x) ? A2($elm$core$List$cons, x, xs) : xs; - }), - _List_Nil, - list); - }); -var $elm$core$List$head = function (list) { - if (list.b) { - var x = list.a; - var xs = list.b; - return $elm$core$Maybe$Just(x); - } else { - return $elm$core$Maybe$Nothing; - } -}; -var $author$project$Main$ActAccumulatorDecrement = {$: 'ActAccumulatorDecrement'}; -var $author$project$Main$uCodeIds = _List_fromArray( - [ - _Utils_Tuple2($author$project$Main$ActAccumulator2DataBus, 'acc2db'), - _Utils_Tuple2($author$project$Main$ActAccumulatorDecrement, 'accDec'), - _Utils_Tuple2($author$project$Main$ActAccumulatorIncrement, 'accInc'), - _Utils_Tuple2($author$project$Main$ActDataBus2Accumulator, 'db2acc'), - _Utils_Tuple2($author$project$Main$ActDataBus2InstructionReg, 'db2ir'), - _Utils_Tuple2($author$project$Main$ActDataBus2Ram, 'db2ram'), - _Utils_Tuple2($author$project$Main$ActInstructionReg2AddressBus, 'ir2ab'), - _Utils_Tuple2($author$project$Main$ActInstructionReg2ProgrammCounter, 'ir2pc'), - _Utils_Tuple2($author$project$Main$ActInstructionReg2UCounter, 'ir2uc'), - _Utils_Tuple2($author$project$Main$ActProgrammCounterIncrement, 'pcInc'), - _Utils_Tuple2($author$project$Main$ActRam2DataBus, 'ram2db'), - _Utils_Tuple2($author$project$Main$ActResetUCounter, 'ucReset'), - _Utils_Tuple2($author$project$Main$ActProgrammCounter2AddressBus, 'pc2ab'), - _Utils_Tuple2($author$project$Main$ActNothing, 'n') - ]); var $author$project$Main$uAction2String = function (action) { var filtered_list = A2( $elm$core$List$filter, @@ -5532,89 +6616,19 @@ var $author$project$Main$cmdSenduUpdate = function (model) { $author$project$Main$sendUUpdate('update') ])); }; -var $elm$json$Json$Decode$bool = _Json_decodeBool; -var $elm$json$Json$Decode$decodeString = _Json_runOnString; -var $elm$json$Json$Decode$field = _Json_decodeField; -var $elm$json$Json$Decode$int = _Json_decodeInt; -var $elm$json$Json$Decode$list = _Json_decodeList; -var $elm$json$Json$Decode$map3 = _Json_map3; -var $elm$json$Json$Decode$map7 = _Json_map7; -var $elm$core$Tuple$second = function (_v0) { - var y = _v0.b; - return y; -}; -var $author$project$Main$string2uAction = function (msg) { - var filtered_list = A2( - $elm$core$List$filter, - function (s) { - return _Utils_eq(s.b, msg); - }, - $author$project$Main$uCodeIds); - var _v0 = $elm$core$List$head(filtered_list); - if (_v0.$ === 'Just') { - var _v1 = _v0.a; - var action = _v1.a; - return $elm$core$Maybe$Just(action); - } else { - return $elm$core$Maybe$Nothing; - } -}; -var $elm$core$Maybe$withDefault = F2( - function (_default, maybe) { - if (maybe.$ === 'Just') { - var value = maybe.a; - return value; - } else { - return _default; - } +var $author$project$Main$decodeModel = F2( + function (model, text) { + var error2maybe = function (err) { + if (err.$ === 'Ok') { + var val = err.a; + return $elm$core$Maybe$Just(val); + } else { + return $elm$core$Maybe$Nothing; + } + }; + return error2maybe( + A2($elm$json$Json$Decode$decodeString, $author$project$Main$modelDecoder, text)); }); -var $author$project$Main$decodeModel = function (text) { - var uCodeDecoder = A2( - $elm$json$Json$Decode$map, - function (s) { - return A2( - $elm$core$Maybe$withDefault, - $author$project$Main$ActNothing, - $author$project$Main$string2uAction(s)); - }, - $elm$json$Json$Decode$string); - var error2maybe = function (err) { - if (err.$ === 'Ok') { - var val = err.a; - return $elm$core$Maybe$Just(val); - } else { - return $elm$core$Maybe$Nothing; - } - }; - return error2maybe( - A2( - $elm$json$Json$Decode$decodeString, - A4( - $elm$json$Json$Decode$map3, - $author$project$Main$Model, - A2( - $elm$json$Json$Decode$field, - 'pc', - A8( - $elm$json$Json$Decode$map7, - $author$project$Main$PC, - A2( - $elm$json$Json$Decode$field, - 'ram', - $elm$json$Json$Decode$list($elm$json$Json$Decode$int)), - A2($elm$json$Json$Decode$field, 'dataBus', $elm$json$Json$Decode$int), - A2($elm$json$Json$Decode$field, 'addressBus', $elm$json$Json$Decode$int), - A2($elm$json$Json$Decode$field, 'instructionReg', $elm$json$Json$Decode$int), - A2($elm$json$Json$Decode$field, 'programmCounter', $elm$json$Json$Decode$int), - A2($elm$json$Json$Decode$field, 'uCounter', $elm$json$Json$Decode$int), - A2($elm$json$Json$Decode$field, 'accumulator', $elm$json$Json$Decode$int))), - A2( - $elm$json$Json$Decode$field, - 'uCode', - $elm$json$Json$Decode$list(uCodeDecoder)), - A2($elm$json$Json$Decode$field, 'autoscroll', $elm$json$Json$Decode$bool)), - text)); -}; var $author$project$Main$actAccumulator2DataBus = function (pc) { return _Utils_update( pc, @@ -5752,6 +6766,23 @@ var $author$project$Main$getAction = function (uAction) { }; } }; +var $author$project$Main$httpError2String = function (err) { + switch (err.$) { + case 'BadUrl': + var str = err.a; + return 'Bad Url: ' + str; + case 'Timeout': + return 'Timeout'; + case 'NetworkError': + return 'Network Error'; + case 'BadStatus': + var num = err.a; + return 'Bad Status: ' + $elm$core$String$fromInt(num); + default: + var str = err.a; + return 'Bad Body: ' + str; + } +}; var $elm$core$Basics$not = _Basics_not; var $author$project$Main$uStepPC = function (model) { var uCounter = model.pc.uCounter; @@ -6014,15 +7045,83 @@ var $author$project$Main$update = F2( return _Utils_Tuple2( model, $author$project$Main$cmdUpdateLocalStorage(model)); - default: + case 'MsgLocalSessionRecieve': var message_in = msg.a; - var _v12 = $author$project$Main$decodeModel(message_in); + var _v12 = A2($author$project$Main$decodeModel, model, message_in); if (_v12.$ === 'Just') { var new_model = _v12.a; - return _Utils_Tuple2(new_model, $elm$core$Platform$Cmd$none); + return _Utils_Tuple2( + _Utils_update( + new_model, + {examples: model.examples}), + $elm$core$Platform$Cmd$none); } else { return _Utils_Tuple2(model, $elm$core$Platform$Cmd$none); } + case 'MsgToggleLoadExample': + return model.exampleChooserOpen ? _Utils_Tuple2( + _Utils_update( + model, + {exampleChooserOpen: false}), + $elm$core$Platform$Cmd$none) : _Utils_Tuple2( + _Utils_update( + model, + {exampleChooserOpen: true}), + $author$project$Main$cmdLoadExamples(model)); + case 'MsgLoadExamplesList': + return _Utils_Tuple2(model, $elm$core$Platform$Cmd$none); + case 'MsgLoadExample': + var i = msg.a; + var _v13 = A2($author$project$Main$valueAt, i, model.examples); + if (_v13.$ === 'Just') { + var example = _v13.a; + return _Utils_Tuple2( + _Utils_update( + model, + {exampleChooserOpen: false}), + A2($author$project$Main$cmdLoadExampleSing, model, example)); + } else { + return _Utils_Tuple2(model, $elm$core$Platform$Cmd$none); + } + case 'MsgLoadExampleArrived': + var result = msg.a; + if (result.$ === 'Ok') { + var new_model = result.a; + return updateModel( + _Utils_update( + model, + {exampleLoaderStatus: $author$project$Main$Success, pc: new_model.pc, uCode: new_model.uCode})); + } else { + var err = result.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + exampleLoaderStatus: $author$project$Main$Failure( + $author$project$Main$httpError2String(err)) + }), + $elm$core$Platform$Cmd$none); + } + default: + var result = msg.a; + if (result.$ === 'Ok') { + var exampleList = result.a; + return _Utils_Tuple2( + _Utils_update( + model, + {examples: exampleList, examplesListStatus: $author$project$Main$Success}), + $elm$core$Platform$Cmd$none); + } else { + var err = result.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + examplesListStatus: $author$project$Main$Failure( + $author$project$Main$httpError2String(err)) + }), + $elm$core$Platform$Cmd$none); + } } }); var $elm$virtual_dom$VirtualDom$lazy = _VirtualDom_lazy; @@ -6031,6 +7130,7 @@ var $author$project$Main$MsgAutoscrollUpdate = {$: 'MsgAutoscrollUpdate'}; var $author$project$Main$MsgInstructionStep = {$: 'MsgInstructionStep'}; var $author$project$Main$MsgLocalSessionExport = {$: 'MsgLocalSessionExport'}; var $author$project$Main$MsgReset = {$: 'MsgReset'}; +var $author$project$Main$MsgToggleLoadExample = {$: 'MsgToggleLoadExample'}; var $author$project$Main$MsgUCycleStep = {$: 'MsgUCycleStep'}; var $elm$html$Html$button = _VirtualDom_node('button'); var $elm$html$Html$Attributes$boolProperty = F2( @@ -6792,6 +7892,158 @@ var $author$project$Main$viewDataBus = function (model) { ])) ])); }; +var $author$project$Main$MsgLoadExample = function (a) { + return {$: 'MsgLoadExample', a: a}; +}; +var $author$project$Main$viewExamplesEntrys = function (model) { + var entry2html = function (_v1) { + var id = _v1.a; + var example = _v1.b; + return A2( + $elm$html$Html$tr, + _List_Nil, + _List_fromArray( + [ + A2( + $elm$html$Html$td, + _List_Nil, + _List_fromArray( + [ + $elm$html$Html$text('Example: ' + example.title) + ])), + A2( + $elm$html$Html$td, + _List_Nil, + _List_fromArray( + [ + A2( + $elm$html$Html$button, + _List_fromArray( + [ + $elm$html$Html$Events$onClick( + $author$project$Main$MsgLoadExample(id)) + ]), + _List_fromArray( + [ + $elm$html$Html$text('Laden') + ])) + ])) + ])); + }; + var _v0 = model.examplesListStatus; + switch (_v0.$) { + case 'Failure': + var msg = _v0.a; + return A2( + $elm$html$Html$div, + _List_Nil, + _List_fromArray( + [ + $elm$html$Html$text('That didn\'t work: ' + msg) + ])); + case 'Waiting': + return A2( + $elm$html$Html$div, + _List_Nil, + _List_fromArray( + [ + $elm$html$Html$text('Loading...') + ])); + default: + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('scroller') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$table, + _List_Nil, + A2( + $elm$core$List$map, + entry2html, + A2($elm$core$List$indexedMap, $elm$core$Tuple$pair, model.examples))) + ])); + } +}; +var $author$project$Main$viewExamples = function (model) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$classList( + _List_fromArray( + [ + _Utils_Tuple2('modal', true), + _Utils_Tuple2('hidden', !model.exampleChooserOpen) + ])) + ]), + _List_fromArray( + [ + A2($elm$html$Html$div, _List_Nil, _List_Nil), + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('modal-card') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$a, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('modal-close'), + $elm$html$Html$Events$onClick($author$project$Main$MsgToggleLoadExample) + ]), + _List_Nil), + A2($elm$html$Html$Lazy$lazy, $author$project$Main$viewExamplesEntrys, model) + ])) + ])); +}; +var $author$project$Main$viewExamplesLoaderError = function (model) { + var _v0 = model.exampleLoaderStatus; + if (_v0.$ === 'Failure') { + var msg = _v0.a; + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('modal') + ]), + _List_fromArray( + [ + A2($elm$html$Html$div, _List_Nil, _List_Nil), + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('modal-card') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$p, + _List_Nil, + _List_fromArray( + [ + $elm$html$Html$text('Something didn\'t work. Please refresh the page') + ])), + A2( + $elm$html$Html$p, + _List_Nil, + _List_fromArray( + [ + $elm$html$Html$text(msg) + ])) + ])) + ])); + } else { + return $elm$html$Html$text(''); + } +}; var $author$project$Main$MsgRamAddBelow = {$: 'MsgRamAddBelow'}; var $author$project$Main$MsgRamEditAddress = F2( function (a, b) { @@ -7144,6 +8396,16 @@ var $author$project$Main$viewPC = function (model) { _List_fromArray( [ $elm$html$Html$text('Export') + ])), + A2( + $elm$html$Html$button, + _List_fromArray( + [ + $elm$html$Html$Events$onClick($author$project$Main$MsgToggleLoadExample) + ]), + _List_fromArray( + [ + $elm$html$Html$text('Load Example') ])) ])), A2( @@ -7168,7 +8430,9 @@ var $author$project$Main$viewPC = function (model) { _List_fromArray( [ A2($elm$html$Html$Lazy$lazy, $author$project$Main$viewDataBus, model) - ])) + ])), + A2($elm$html$Html$Lazy$lazy, $author$project$Main$viewExamples, model), + A2($elm$html$Html$Lazy$lazy, $author$project$Main$viewExamplesLoaderError, model) ])); }; var $author$project$Main$view = function (model) { diff --git a/src/Main.elm b/src/Main.elm index 5d11532..bfc6030 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -14,8 +14,10 @@ import Html exposing (address) import Json.Encode as JE import Json.Decode as JD import Html.Events exposing (targetValue) +import Http modelVersion = 1 +examplesListUrl = "examples-list.json" -- Note that general Stuff is at the end of the document -- PORTS @@ -45,8 +47,21 @@ type alias Model = { pc : PC , uCode : List UAction , autoscroll : Bool + , examples : List Example + , exampleChooserOpen : Bool + , examplesListStatus : LoaderState + , exampleLoaderStatus : LoaderState } +type alias Example = + { title : String + , version : String + , url : String + , enabled : Bool + } + +type LoaderState = Failure String | Waiting | Success + type UAction = ActAccumulator2DataBus @@ -64,7 +79,6 @@ type UAction | ActProgrammCounter2AddressBus | ActNothing - uCodeDescriptions : List ( UAction, String ) uCodeDescriptions = [ ( ActAccumulator2DataBus, "Acc -> DataBus" ) @@ -230,6 +244,11 @@ type Msg | MsgAluEdit String | MsgLocalSessionExport | MsgLocalSessionRecieve String + | MsgToggleLoadExample + | MsgLoadExamplesList + | MsgLoadExample Int + | MsgLoadExampleArrived (Result Http.Error Model) + | MsgExamplesArrived (Result Http.Error (List Example)) update : Msg -> Model -> ( Model, Cmd Msg ) @@ -361,13 +380,52 @@ update msg model = ( model, cmdUpdateLocalStorage model ) MsgLocalSessionRecieve message_in -> - case decodeModel message_in of + case decodeModel model message_in of Just new_model -> - ( new_model , Cmd.none ) + ( { new_model | examples = model.examples } , Cmd.none ) _ -> ( model, Cmd.none ) + MsgToggleLoadExample -> + if model.exampleChooserOpen then + ( { model | exampleChooserOpen = False } + , Cmd.none ) + else + ( { model | exampleChooserOpen = True } + , cmdLoadExamples model) + MsgLoadExamplesList -> + ( model, Cmd.none ) + + MsgLoadExample i -> + case valueAt i model.examples of + Just example -> + ({ model | exampleChooserOpen = False } + , cmdLoadExampleSing model example ) + Nothing -> + ( model, Cmd.none ) + + MsgLoadExampleArrived result -> + case result of + Ok new_model -> + updateModel { model | pc = new_model.pc + , uCode = new_model.uCode + , exampleLoaderStatus = Success } + Err err -> + ( { model | exampleLoaderStatus = Failure <| httpError2String err } + , Cmd.none ) + + + MsgExamplesArrived result -> + case result of + Ok exampleList -> + ( { model | examples = exampleList, examplesListStatus = Success } + , Cmd.none ) + Err err -> + ( { model | examplesListStatus = Failure <| httpError2String err } + , Cmd.none ) + + -- Practically a part of uStepPC but sepeated for manual mode getAction : UAction -> (PC -> PC) getAction uAction = @@ -443,41 +501,53 @@ encodeModel model = ] |> JE.encode 0 - -decodeModel : String -> Maybe Model -decodeModel text = +decodeModel : Model -> String -> Maybe Model +decodeModel model text = let error2maybe err = case err of Ok val -> Just val _ -> Nothing - - uCodeDecoder = - JD.map - (\s -> Maybe.withDefault ActNothing <| string2uAction s ) - (JD.string) in text - |> JD.decodeString - ( JD.map3 - Model - ( JD.field "pc" - ( JD.map7 - PC - (JD.field "ram" (JD.list JD.int)) - (JD.field "dataBus" JD.int) - (JD.field "addressBus" JD.int) - (JD.field "instructionReg" JD.int) - (JD.field "programmCounter" JD.int) - (JD.field "uCounter" JD.int) - (JD.field "accumulator" JD.int) - ) - ) - ( JD.field "uCode" (JD.list uCodeDecoder) ) - ( JD.field "autoscroll" JD.bool ) - ) + |> JD.decodeString modelDecoder |> error2maybe +exampleListDecoder : JD.Decoder (List Example) +exampleListDecoder = + JD.field "available" + <| JD.list + <| JD.map4 + Example + ( JD.field "title" JD.string ) + ( JD.field "version" JD.string ) + ( JD.field "url" JD.string ) + ( JD.field "enabled" (JD.map (\s -> s == 1) JD.int) ) + +modelDecoder : JD.Decoder Model +modelDecoder = + JD.map3 + (\a b c -> Model a b c [] False Waiting Waiting) + ( JD.field "pc" + ( JD.map7 + PC + (JD.field "ram" (JD.list JD.int)) + (JD.field "dataBus" JD.int) + (JD.field "addressBus" JD.int) + (JD.field "instructionReg" JD.int) + (JD.field "programmCounter" JD.int) + (JD.field "uCounter" JD.int) + (JD.field "accumulator" JD.int) + ) + ) + ( JD.field "uCode" + <| JD.list + <| JD.map (\s -> Maybe.withDefault ActNothing <| string2uAction s ) + <| JD.string + ) + ( JD.field "autoscroll" JD.bool ) + + cmdUpdateLocalStorage : Model -> Cmd Msg cmdUpdateLocalStorage model = localStorageSend (encodeModel model) @@ -489,6 +559,30 @@ cmdSenduUpdate model = , sendUUpdate "update" ] + +cmdLoadExamples : Model -> Cmd Msg +cmdLoadExamples model = + Http.get + { url = examplesListUrl + , expect = Http.expectJson MsgExamplesArrived exampleListDecoder + } + +cmdLoadExampleSing : Model -> Example -> Cmd Msg +cmdLoadExampleSing model example = + Http.get + { url = example.url + , expect = Http.expectJson MsgLoadExampleArrived modelDecoder + } + +httpError2String : Http.Error -> String +httpError2String err = + case err of + Http.BadUrl str -> "Bad Url: " ++ str + Http.Timeout -> "Timeout" + Http.NetworkError -> "Network Error" + Http.BadStatus num -> "Bad Status: " ++ String.fromInt num + Http.BadBody str -> "Bad Body: " ++ str + -- VIEWERS view : Model -> Html Msg @@ -523,12 +617,15 @@ viewPC model = [ text "Autoscroll" ] ] , button [ onClick MsgLocalSessionExport ] [ text "Export" ] + , button [ onClick MsgToggleLoadExample ] [ text "Load Example" ] ] , div [ class "grid-fullwidth" ] [ lazy viewAddressBus model ] , lazy viewRam model , lazy viewCu model , lazy viewAlu model , div [ class "grid-fullwidth" ] [ lazy viewDataBus model ] + , lazy viewExamples model + , lazy viewExamplesLoaderError model ] @@ -800,8 +897,50 @@ viewInstrEntry i = text ( (addLeadingZero instruction 3) ++ " " ++ (addLeadingZero address 5) ) - +viewExamples : Model -> Html Msg +viewExamples model = + div [ classList [("modal", True), ("hidden", (not model.exampleChooserOpen))] ] + [ div [] [] + , div [ class "modal-card" ] + [ Html.a [ class "modal-close", onClick MsgToggleLoadExample ] [] + , lazy viewExamplesEntrys model + ] + ] +viewExamplesEntrys : Model -> Html Msg +viewExamplesEntrys model = + let + entry2html (id, example) = + Html.tr [] + [ Html.td [] [ text <| "Example: " ++ example.title ] + , Html.td [] [ button [ onClick <| MsgLoadExample id ] [ text "Laden" ] ] + ] + in + case model.examplesListStatus of + Failure msg -> + div [] [ text <| "That didn't work: " ++ msg] + Waiting -> + div [] [ text "Loading..." ] + Success -> + div [ class "scroller" ] + [ Html.table [] + <| List.map entry2html + <| List.indexedMap Tuple.pair model.examples + ] + + +viewExamplesLoaderError : Model -> Html Msg +viewExamplesLoaderError model = + case model.exampleLoaderStatus of + Failure msg -> + div [ class "modal" ] + [ div [] [] + , div [ class "modal-card" ] + [ Html.p [] [ text "Something didn't work. Please refresh the page"] + , Html.p [] [ text msg ] + ] + ] + _ -> text "" -- END VIEWERS -- ACTIONS @@ -1013,7 +1152,7 @@ subscriptions model = init : () -> ( Model, Cmd Msg ) init flags = - ( Model initialPC initialUCodes True, Cmd.none ) + ( Model initialPC initialUCodes True [] False Waiting Waiting, Cmd.none ) main : Program () Model Msg