From 6488db016bb1f79c0f01ae9828a6519e63d578e2 Mon Sep 17 00:00:00 2001 From: Chris Vanderloo Date: Tue, 28 Apr 2020 09:46:42 -0400 Subject: [PATCH] Updates --- asset-manifest.json | 14 +++++++------- index.html | 2 +- ...he-manifest.67fef1a7b6fceebe463b62be04ac992e.js | 10 +++++----- service-worker.js | 2 +- ....440711dd.chunk.css => main.21033f84.chunk.css} | 2 +- static/css/main.21033f84.chunk.css.map | 1 + static/css/main.440711dd.chunk.css.map | 1 - ...in.f79f5540.chunk.js => main.70ebaa88.chunk.js} | 2 +- static/js/main.70ebaa88.chunk.js.map | 1 + static/js/main.f79f5540.chunk.js.map | 1 - 10 files changed, 18 insertions(+), 18 deletions(-) rename precache-manifest.d9ae7b0f18d72a3029aa1bd8cc15cc83.js => precache-manifest.67fef1a7b6fceebe463b62be04ac992e.js (97%) rename static/css/{main.440711dd.chunk.css => main.21033f84.chunk.css} (98%) create mode 100644 static/css/main.21033f84.chunk.css.map delete mode 100644 static/css/main.440711dd.chunk.css.map rename static/js/{main.f79f5540.chunk.js => main.70ebaa88.chunk.js} (99%) create mode 100644 static/js/main.70ebaa88.chunk.js.map delete mode 100644 static/js/main.f79f5540.chunk.js.map diff --git a/asset-manifest.json b/asset-manifest.json index c941143..1ac66d0 100644 --- a/asset-manifest.json +++ b/asset-manifest.json @@ -1,18 +1,18 @@ { "files": { - "main.css": "/existential-graphs/static/css/main.440711dd.chunk.css", - "main.js": "/existential-graphs/static/js/main.f79f5540.chunk.js", - "main.js.map": "/existential-graphs/static/js/main.f79f5540.chunk.js.map", + "main.css": "/existential-graphs/static/css/main.21033f84.chunk.css", + "main.js": "/existential-graphs/static/js/main.70ebaa88.chunk.js", + "main.js.map": "/existential-graphs/static/js/main.70ebaa88.chunk.js.map", "runtime-main.js": "/existential-graphs/static/js/runtime-main.1b28495f.js", "runtime-main.js.map": "/existential-graphs/static/js/runtime-main.1b28495f.js.map", "static/css/2.dea1b1f8.chunk.css": "/existential-graphs/static/css/2.dea1b1f8.chunk.css", "static/js/2.9e46875a.chunk.js": "/existential-graphs/static/js/2.9e46875a.chunk.js", "static/js/2.9e46875a.chunk.js.map": "/existential-graphs/static/js/2.9e46875a.chunk.js.map", "index.html": "/existential-graphs/index.html", - "precache-manifest.d9ae7b0f18d72a3029aa1bd8cc15cc83.js": "/existential-graphs/precache-manifest.d9ae7b0f18d72a3029aa1bd8cc15cc83.js", + "precache-manifest.67fef1a7b6fceebe463b62be04ac992e.js": "/existential-graphs/precache-manifest.67fef1a7b6fceebe463b62be04ac992e.js", "service-worker.js": "/existential-graphs/service-worker.js", "static/css/2.dea1b1f8.chunk.css.map": "/existential-graphs/static/css/2.dea1b1f8.chunk.css.map", - "static/css/main.440711dd.chunk.css.map": "/existential-graphs/static/css/main.440711dd.chunk.css.map", + "static/css/main.21033f84.chunk.css.map": "/existential-graphs/static/css/main.21033f84.chunk.css.map", "static/js/2.9e46875a.chunk.js.LICENSE.txt": "/existential-graphs/static/js/2.9e46875a.chunk.js.LICENSE.txt", "static/media/katex.min.css": "/existential-graphs/static/media/KaTeX_Typewriter-Regular.6cc31ea5.woff2" }, @@ -20,7 +20,7 @@ "static/js/runtime-main.1b28495f.js", "static/css/2.dea1b1f8.chunk.css", "static/js/2.9e46875a.chunk.js", - "static/css/main.440711dd.chunk.css", - "static/js/main.f79f5540.chunk.js" + "static/css/main.21033f84.chunk.css", + "static/js/main.70ebaa88.chunk.js" ] } \ No newline at end of file diff --git a/index.html b/index.html index df774b3..3ffeead 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -React App
\ No newline at end of file +React App
\ No newline at end of file diff --git a/precache-manifest.d9ae7b0f18d72a3029aa1bd8cc15cc83.js b/precache-manifest.67fef1a7b6fceebe463b62be04ac992e.js similarity index 97% rename from precache-manifest.d9ae7b0f18d72a3029aa1bd8cc15cc83.js rename to precache-manifest.67fef1a7b6fceebe463b62be04ac992e.js index 7772bfd..6f25ed5 100644 --- a/precache-manifest.d9ae7b0f18d72a3029aa1bd8cc15cc83.js +++ b/precache-manifest.67fef1a7b6fceebe463b62be04ac992e.js @@ -1,6 +1,6 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([ { - "revision": "261973d5d6a4383be5998c7d6813ee46", + "revision": "4270aa2fc8e57ebb258810ed4b25ad23", "url": "/existential-graphs/index.html" }, { @@ -8,8 +8,8 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([ "url": "/existential-graphs/static/css/2.dea1b1f8.chunk.css" }, { - "revision": "31410478b9dea4c6735f", - "url": "/existential-graphs/static/css/main.440711dd.chunk.css" + "revision": "df2187f3f9808d21f346", + "url": "/existential-graphs/static/css/main.21033f84.chunk.css" }, { "revision": "f21068636de49040a692", @@ -20,8 +20,8 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([ "url": "/existential-graphs/static/js/2.9e46875a.chunk.js.LICENSE.txt" }, { - "revision": "31410478b9dea4c6735f", - "url": "/existential-graphs/static/js/main.f79f5540.chunk.js" + "revision": "df2187f3f9808d21f346", + "url": "/existential-graphs/static/js/main.70ebaa88.chunk.js" }, { "revision": "dc57d5fed269a7aa898b", diff --git a/service-worker.js b/service-worker.js index adce926..62e9a8a 100644 --- a/service-worker.js +++ b/service-worker.js @@ -14,7 +14,7 @@ importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js"); importScripts( - "/existential-graphs/precache-manifest.d9ae7b0f18d72a3029aa1bd8cc15cc83.js" + "/existential-graphs/precache-manifest.67fef1a7b6fceebe463b62be04ac992e.js" ); self.addEventListener('message', (event) => { diff --git a/static/css/main.440711dd.chunk.css b/static/css/main.21033f84.chunk.css similarity index 98% rename from static/css/main.440711dd.chunk.css rename to static/css/main.21033f84.chunk.css index 35871c3..5536c80 100644 --- a/static/css/main.440711dd.chunk.css +++ b/static/css/main.21033f84.chunk.css @@ -1,2 +1,2 @@ @import url(https://fonts.googleapis.com/css2?family=Heebo:wght@400;500;800&family=Open+Sans:ital,wght@0,300;0,400;0,700;1,400&display=swap);*,:after,:before{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-ms-box-sizing:border-box}body{font-family:"Open Sans",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}h1,h2,h3,h4,h5,h6{font-family:"Heebo",sans-serif;margin:0}p{margin:0}h1{font-size:42px;line-height:62px}code{font-family:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace}.App,body,html{width:100%;height:100%;margin:0;padding:0;overflow:hidden}.whiteBG{background-color:#fff!important}.initial{background-color:#f0f0f0;height:100vh;width:100vw;transition:background-color 1s}input{font-size:1em;highlight:none;border-radius:0;outline:none}button{background-color:#9aa899;border:none;color:#fff;padding:15px 32px;text-align:center;text-decoration:none;display:inline-block;font-size:16px;margin-right:30px;box-shadow:0 0 10px rgba(0,0,0,.23),0 2px 3px rgba(0,0,0,.34)}button:hover{box-shadow:0 0 7px rgba(0,0,0,.16),0 2px 2px rgba(0,0,0,.24)}button:active{box-shadow:0 0 2px rgba(0,0,0,.09),0 0 1px rgba(0,0,0,.16)}.canvas{width:100vw;height:100vh}.abs{display:absolute}.noselect{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.toolbox{position:absolute;display:inline-block;width:200px;float:left;background-color:#eaeaea;margin:10px;border-radius:25px;padding:15px 10px;box-shadow:0 0 7px rgba(0,0,0,.16),0 2px 2px rgba(0,0,0,.24);z-index:1}.toolbox h3{margin-left:5px}.tool{background-color:#dfdfda;border-radius:15px;margin-top:5px;padding:4px 4px 4px 16px}.tool:hover{background-color:#dadaca;cursor:pointer}.hoverEl{padding:5px;border-radius:10px;cursor:pointer}.hoverEl:hover{background-color:#e2dbbe}.step-text{height:22px;width:89px;color:#848484;font-family:"Open Sans";font-size:16px;line-height:22px;bottom:20px}.step-menu,.step-text{text-align:center;position:absolute;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.step-menu{bottom:53px;box-sizing:border-box;height:73px;line-height:73px;width:278px;border-radius:36.5px;background-color:#eaeaea;border:1px solid #e6e6e6;box-shadow:0 0 8px 0 rgba(0,0,0,.28)}.step-menu div{display:inline-block;margin-top:2.6px;margin-left:22px}.step-menu div:first-child{margin-left:0}body,h1,h2{color:#1a1423}h3,h4,h5,h6{color:#66666e}.formulaTable{table-layout:fixed;width:100%;border-collapse:collapse}.formulaTable .plus{padding-right:5px;padding-left:3px}.formulaTable .plus:before{content:"+"}.formulaTable tr{border:1px solid #ddd;height:40px}.formulaTable td{vertical-align:middle;padding:5px;height:25px;background-color:#fafafa}.formulaTable td.interactive{cursor:pointer;color:#848484}.formulaTable td.interactive:hover{color:#545454}.formulaTable td.close{width:30px}h2{padding-top:15px}input{height:25px;width:100%;padding:15px;border-radius:4px;border:1px solid #ddd;max-width:375px}.floating-window.shown{top:50%!important}.floating-window{transition:top 1s;position:absolute;height:720px;width:980px;border-radius:25px;top:-50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);background-color:#fff;box-shadow:0 4px 10px 0 rgba(0,0,0,.11);overflow:hidden}.floating-window .toolbar{position:absolute;bottom:0;height:68px;width:100%;border-radius:0 0 25px 25px;background-color:#eaeaea;display:flex;flex-direction:row-reverse;padding:6px 20px 6px 6px}.floating-window .toolbar .svg{display:inline-block;padding-right:10px}.floating-window .toolbar .back{position:absolute;top:8px;left:20px;background:none;color:#848484;box-shadow:none!important}.floating-window .toolbar button{width:126px;border-radius:15px;margin:2px 6px 2px 0;box-shadow:0 0 10px 0 rgba(0,0,0,.1);transition:.1s;color:#fff}.floating-window .toolbar button:hover{box-shadow:0 0 6px 0 rgba(0,0,0,.3)}.floating-window .toolbar button:active{box-shadow:0 0 2px 0 rgba(0,0,0,.5);color:#ccc}.floating-window .full-width{padding:40px 60px!important}.floating-window .content{padding:20px;height:720px;overflow:auto}.floating-window .content p{font-size:18px;line-height:25px}.floating-window .content .column{padding:20px 40px;float:left;width:50%}.floating-window .content:after{content:"";display:block;clear:both;height:80px}.floating-window .content .divider{position:absolute;top:0;left:50%;height:100%;width:1px;background-color:#b7b7b7} -/*# sourceMappingURL=main.440711dd.chunk.css.map */ \ No newline at end of file +/*# sourceMappingURL=main.21033f84.chunk.css.map */ \ No newline at end of file diff --git a/static/css/main.21033f84.chunk.css.map b/static/css/main.21033f84.chunk.css.map new file mode 100644 index 0000000..3ebd4e6 --- /dev/null +++ b/static/css/main.21033f84.chunk.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["main.21033f84.chunk.css","index.scss","App.scss","Canvas.scss","../colors.scss","CreateNew.scss","intro.scss"],"names":[],"mappings":"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","file":"main.21033f84.chunk.css","sourcesContent":["@import url(https://fonts.googleapis.com/css2?family=Heebo:wght@400;500;800&family=Open+Sans:ital,wght@0,300;0,400;0,700;1,400&display=swap);\nbody{color:#1A1423}h1,h2{color:#1A1423}h3,h4,h5,h6{color:#66666E}*,*:before,*:after{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-ms-box-sizing:border-box}body{font-family:'Open Sans', sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}h1,h2,h3,h4,h5,h6{font-family:'Heebo', sans-serif;margin:0}p{margin:0}h1{font-size:42px;line-height:62px}code{font-family:source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace}\n\nhtml,body,.App{width:100%;height:100%;margin:0;padding:0;overflow:hidden}.whiteBG{background-color:#FFFFFF !important}.initial{background-color:#F0F0F0;height:100vh;width:100vw;transition:background-color 1s}input{font-size:1em;highlight:none;border-radius:0;outline:none}button{background-color:#9AA899;border:none;color:white;padding:15px 32px;text-align:center;text-decoration:none;display:inline-block;font-size:16px;margin-right:30px;box-shadow:0 0px 10px rgba(0,0,0,0.23),0 2px 3px rgba(0,0,0,0.34)}button:hover{box-shadow:0 0px 7px rgba(0,0,0,0.16),0 2px 2px rgba(0,0,0,0.24)}button:active{box-shadow:0 0px 2px rgba(0,0,0,0.09),0 0px 1px rgba(0,0,0,0.16)}\n\nbody{color:#1A1423}h1,h2{color:#1A1423}h3,h4,h5,h6{color:#66666E}.canvas{width:100vw;height:100vh}.abs{display:absolute}.noselect{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.toolbox{position:absolute;display:inline-block;width:200px;float:left;background-color:#EAEAEA;margin:10px;border-radius:25px;padding:15px;padding-left:10px;padding-right:10px;box-shadow:0 0px 7px rgba(0,0,0,0.16),0 2px 2px rgba(0,0,0,0.24);z-index:1}.toolbox h3{margin-left:5px}.tool{background-color:#DFDFDA;border-radius:15px;padding:4px;margin-top:5px;padding-left:16px}.tool:hover{background-color:#DADACA;cursor:pointer}.hoverEl{padding:5px;border-radius:10px;cursor:pointer}.hoverEl:hover{background-color:#e2dbbe}.step-text{height:22px;width:89px;color:#848484;font-family:\"Open Sans\";font-size:16px;line-height:22px;text-align:center;position:absolute;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);bottom:20px}.step-menu{position:absolute;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);bottom:53px;box-sizing:border-box;height:73px;line-height:73px;width:278px;border-radius:36.5px;background-color:#EAEAEA;border:1px solid #E6E6E6;box-shadow:0 0 8px 0 rgba(0,0,0,0.28);text-align:center}.step-menu div{display:inline-block;margin-top:2.6px;margin-left:22px}.step-menu div:first-child{margin-left:0}\n\nbody{color:#1A1423}h1,h2{color:#1A1423}h3,h4,h5,h6{color:#66666E}.formulaTable{table-layout:fixed;width:100%;border-collapse:collapse}.formulaTable .plus{padding-right:5px;padding-left:3px}.formulaTable .plus:before{content:'+'}.formulaTable tr{border:1px solid #DDD;height:40px}.formulaTable td{vertical-align:middle;padding:5px;height:25px;background-color:#FAFAFA}.formulaTable td.interactive{cursor:pointer;color:#848484}.formulaTable td.interactive:hover{color:#545454}.formulaTable td.close{width:30px}h2{padding-top:15px}input{height:25px;width:100%;padding:15px;border-radius:4px;border:1px solid #DDD;max-width:375px}\n\n.floating-window.shown{top:50% !important}.floating-window{transition:top 1s;position:absolute;height:720px;width:980px;border-radius:25px;top:-50%;left:50%;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);background-color:white;box-shadow:0 4px 10px 0 rgba(0,0,0,0.11);overflow:hidden}.floating-window .toolbar{position:absolute;bottom:0;height:68px;width:100%;border-radius:0 0 25px 25px;background-color:#EAEAEA;display:flex;flex-direction:row-reverse;padding:6px;padding-right:20px}.floating-window .toolbar .svg{display:inline-block;padding-right:10px}.floating-window .toolbar .back{position:absolute;top:8px;left:20px;background:none;color:#848484;box-shadow:none !important}.floating-window .toolbar button{width:126px;border-radius:15px;margin:0;margin-right:6px;margin-top:2px;margin-bottom:2px;box-shadow:0 0 10px 0 rgba(0,0,0,0.1);transition:0.1s;color:white}.floating-window .toolbar button:hover{box-shadow:0 0 6px 0 rgba(0,0,0,0.3)}.floating-window .toolbar button:active{box-shadow:0 0 2px 0 rgba(0,0,0,0.5);color:#CCC}.floating-window .full-width{padding:40px 60px !important}.floating-window .content{padding:20px;height:720px;overflow:auto}.floating-window .content p{font-size:18px;line-height:25px}.floating-window .content .column{padding:20px 40px;float:left;width:50%}.floating-window .content:after{content:\"\";display:block;clear:both;height:80px}.floating-window .content .divider{position:absolute;top:0;left:50%;height:100%;width:1px;background-color:#B7B7B7}\n\n","// https://coolors.co/e2dbbe-9aa899-1a1423-66666e-9999a1\n\n@import 'colors';\n@import url('https://fonts.googleapis.com/css2?family=Heebo:wght@400;500;800&family=Open+Sans:ital,wght@0,300;0,400;0,700;1,400&display=swap');\n\n* , *:before, *:after{ \n box-sizing:border-box; \n -moz-box-sizing:border-box; \n -webkit-box-sizing:border-box; \n -ms-box-sizing:border-box;\n}\n\nbody {\n font-family: 'Open Sans', sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\nh1,h2,h3,h4,h5,h6 {\n font-family: 'Heebo', sans-serif;\n margin: 0;\n}\np {\n margin: 0;\n}\nh1 {\n font-size: 42px;\n line-height: 62px;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',\n monospace;\n}\n","html, body, .App {\n width:100%; \n height:100%; \n margin:0; \n padding:0;\n overflow: hidden; \n}\n\n.whiteBG {\n background-color: #FFFFFF !important;\n}\n\n.initial {\n background-color: #F0F0F0;\n height: 100vh;\n width: 100vw;\n transition: background-color 1s;\n}\n\ninput {\n font-size: 1em;\n highlight: none;\n border-radius: 0;\n outline: none;\n}\n\nbutton {\n background-color: #9AA899;\n border: none;\n color: white;\n padding: 15px 32px;\n text-align: center;\n text-decoration: none;\n display: inline-block;\n font-size: 16px;\n margin-right: 30px;\n box-shadow: 0 0px 10px rgba(0,0,0,0.23), 0 2px 3px rgba(0,0,0,0.34);\n &:hover {\n box-shadow: 0 0px 7px rgba(0,0,0,0.16), 0 2px 2px rgba(0,0,0,0.24);\n }\n &:active {\n box-shadow: 0 0px 2px rgba(0,0,0,0.09), 0 0px 1px rgba(0,0,0,0.16);\n }\n}","@import '../colors';\n\n.canvas { \n width: 100vw;\n height: 100vh;\n}\n\n.abs {\n display: absolute;\n}\n\n.noselect {\n -webkit-touch-callout: none; /* iOS Safari */\n -webkit-user-select: none; /* Safari */\n -khtml-user-select: none; /* Konqueror HTML */\n -moz-user-select: none; /* Old versions of Firefox */\n -ms-user-select: none; /* Internet Explorer/Edge */\n user-select: none; /* Non-prefixed version, currently\n supported by Chrome, Opera and Firefox */\n}\n\n.toolbox {\n position: absolute;\n display: inline-block;\n width: 200px;\n float: left;\n background-color: $white-gray;\n margin: 10px;\n border-radius: 25px;\n padding: 15px;\n padding-left: 10px;\n padding-right: 10px;\n box-shadow: 0 0px 7px rgba(0,0,0,0.16), 0 2px 2px rgba(0,0,0,0.24);\n z-index: 1;\n h3 {\n margin-left: 5px;\n }\n}\n\n.tool {\n background-color: #DFDFDA;\n border-radius: 15px;\n padding: 4px;\n margin-top: 5px;\n padding-left: 16px;\n &:hover {\n background-color: #DADACA;\n cursor: pointer;\n }\n}\n\n.hoverEl {\n padding: 5px;\n border-radius: 10px;\n cursor: pointer;\n &:hover {\n background-color: $tan;\n }\n}\n\n.step-text {\n height: 22px;\n width: 89px;\n color: #848484;\n font-family: \"Open Sans\";\n font-size: 16px;\n line-height: 22px;\n text-align: center;\n position: absolute;\n left: 50%;\n -webkit-transform: translateX(-50%);\n transform: translateX(-50%);\n bottom: 20px;\n}\n\n.step-menu {\n position: absolute;\n left: 50%;\n -webkit-transform: translateX(-50%);\n transform: translateX(-50%);\n bottom: 53px;\n box-sizing: border-box;\n height: 73px;\n line-height: 73px;\n width: 278px;\n border-radius: 36.5px;\n background-color: #EAEAEA;\n border: 1px solid #E6E6E6;\n box-shadow: 0 0 8px 0 rgba(0,0,0,0.28);\n text-align: center;\n div {\n display: inline-block;\n margin-top: 2.6px;\n margin-left: 22px;\n &:first-child {\n margin-left: 0;\n }\n }\n}","$tan: #e2dbbe;\n$green: #9AA899;\n$black: #1A1423;\n$gray: #66666E;\n$light-gray: #9999A1;\n$white-gray: #EAEAEA;\n\nbody {\n color: $black;\n}\n\nh1,h2 {\n color: $black;\n}\n\nh3,h4,h5,h6 {\n color: $gray;\n}","@import '../colors';\n\n.formulaTable {\n table-layout: fixed;\n width: 100%;\n border-collapse: collapse;\n .plus {\n &:before {\n content: '+';\n }\n padding-right: 5px;\n padding-left: 3px;\n }\n tr {\n border: 1px solid #DDD;\n height: 40px;\n }\n td {\n vertical-align: middle;\n padding: 5px;\n height: 25px;\n background-color: #FAFAFA; \n }\n td.interactive {\n cursor: pointer;\n color: #848484;\n &:hover {\n color: #545454;\n }\n }\n td.close {\n width: 30px;\n }\n}\n\nh2 {\n padding-top: 15px;\n}\n\ninput {\n height: 25px;\n width: 100%;\n padding: 15px;\n border-radius: 4px;\n border: 1px solid #DDD;\n max-width: 375px;\n}",".floating-window.shown {\n top: 50% !important;\n}\n\n.floating-window {\n transition: top 1s;\n position: absolute;\n height: 720px;\n width: 980px;\n border-radius: 25px;\n top: -50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background-color: white;\n box-shadow: 0 4px 10px 0 rgba(0,0,0,0.11);\n overflow: hidden;\n .toolbar {\n position: absolute;\n bottom: 0;\n height: 68px;\n width: 100%;\n border-radius: 0 0 25px 25px;\n background-color: #EAEAEA;\n display: flex;\n flex-direction: row-reverse;\n padding: 6px;\n padding-right: 20px;\n .svg {\n display: inline-block;\n padding-right: 10px;\n }\n .back {\n position: absolute;\n top: 8px;\n left: 20px;\n background: none;\n color: #848484;\n box-shadow: none !important;\n }\n button {\n width: 126px;\n border-radius: 15px;\n margin: 0;\n margin-right: 6px;\n margin-top: 2px;\n margin-bottom: 2px;\n box-shadow: 0 0 10px 0 rgba(0,0,0,0.1);\n transition: 0.1s;\n color: white;\n &:hover {\n box-shadow: 0 0 6px 0 rgba(0,0,0,0.3);\n }\n &:active {\n box-shadow: 0 0 2px 0 rgba(0,0,0,0.5);\n color: #CCC;\n }\n }\n }\n .full-width {\n padding: 40px 60px !important;\n }\n .content {\n padding: 20px;\n height: 720px;\n overflow: auto;\n p {\n font-size: 18px;\n line-height: 25px;\n }\n .column {\n padding: 20px 40px;\n float: left;\n width: 50%;\n }\n &:after {\n content: \"\";\n display: block;\n clear: both;\n height: 80px;\n }\n .divider {\n position: absolute;\n top: 0;\n left: 50%;\n height: 100%;\n width: 1px;\n background-color: #B7B7B7;\n }\n }\n}"]} \ No newline at end of file diff --git a/static/css/main.440711dd.chunk.css.map b/static/css/main.440711dd.chunk.css.map deleted file mode 100644 index 4b8caf6..0000000 --- a/static/css/main.440711dd.chunk.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["main.440711dd.chunk.css","index.scss"],"names":[],"mappings":"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","file":"main.440711dd.chunk.css","sourcesContent":["@import url(https://fonts.googleapis.com/css2?family=Heebo:wght@400;500;800&family=Open+Sans:ital,wght@0,300;0,400;0,700;1,400&display=swap);\nbody{color:#1A1423}h1,h2{color:#1A1423}h3,h4,h5,h6{color:#66666E}*,*:before,*:after{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-ms-box-sizing:border-box}body{font-family:'Open Sans', sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}h1,h2,h3,h4,h5,h6{font-family:'Heebo', sans-serif;margin:0}p{margin:0}h1{font-size:42px;line-height:62px}code{font-family:source-code-pro, Menlo, Monaco, Consolas, 'Courier New',\r monospace}\n\nhtml,body,.App{width:100%;height:100%;margin:0;padding:0;overflow:hidden}.whiteBG{background-color:#FFFFFF !important}.initial{background-color:#F0F0F0;height:100vh;width:100vw;transition:background-color 1s}input{font-size:1em;highlight:none;border-radius:0;outline:none}button{background-color:#9AA899;border:none;color:white;padding:15px 32px;text-align:center;text-decoration:none;display:inline-block;font-size:16px;margin-right:30px;box-shadow:0 0px 10px rgba(0,0,0,0.23),0 2px 3px rgba(0,0,0,0.34)}button:hover{box-shadow:0 0px 7px rgba(0,0,0,0.16),0 2px 2px rgba(0,0,0,0.24)}button:active{box-shadow:0 0px 2px rgba(0,0,0,0.09),0 0px 1px rgba(0,0,0,0.16)}\n\nbody{color:#1A1423}h1,h2{color:#1A1423}h3,h4,h5,h6{color:#66666E}.canvas{width:100vw;height:100vh}.abs{display:absolute}.noselect{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.toolbox{position:absolute;display:inline-block;width:200px;float:left;background-color:#EAEAEA;margin:10px;border-radius:25px;padding:15px;padding-left:10px;padding-right:10px;box-shadow:0 0px 7px rgba(0,0,0,0.16),0 2px 2px rgba(0,0,0,0.24);z-index:1}.toolbox h3{margin-left:5px}.tool{background-color:#DFDFDA;border-radius:15px;padding:4px;margin-top:5px;padding-left:16px}.tool:hover{background-color:#DADACA;cursor:pointer}.hoverEl{padding:5px;border-radius:10px;cursor:pointer}.hoverEl:hover{background-color:#e2dbbe}.step-text{height:22px;width:89px;color:#848484;font-family:\"Open Sans\";font-size:16px;line-height:22px;text-align:center;position:absolute;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);bottom:20px}.step-menu{position:absolute;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);bottom:53px;box-sizing:border-box;height:73px;line-height:73px;width:278px;border-radius:36.5px;background-color:#EAEAEA;border:1px solid #E6E6E6;box-shadow:0 0 8px 0 rgba(0,0,0,0.28);text-align:center}.step-menu div{display:inline-block;margin-top:2.6px;margin-left:22px}.step-menu div:first-child{margin-left:0}\n\nbody{color:#1A1423}h1,h2{color:#1A1423}h3,h4,h5,h6{color:#66666E}.formulaTable{table-layout:fixed;width:100%;border-collapse:collapse}.formulaTable .plus{padding-right:5px;padding-left:3px}.formulaTable .plus:before{content:'+'}.formulaTable tr{border:1px solid #DDD;height:40px}.formulaTable td{vertical-align:middle;padding:5px;height:25px;background-color:#FAFAFA}.formulaTable td.interactive{cursor:pointer;color:#848484}.formulaTable td.interactive:hover{color:#545454}.formulaTable td.close{width:30px}h2{padding-top:15px}input{height:25px;width:100%;padding:15px;border-radius:4px;border:1px solid #DDD;max-width:375px}\n\n.floating-window.shown{top:50% !important}.floating-window{transition:top 1s;position:absolute;height:720px;width:980px;border-radius:25px;top:-50%;left:50%;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);background-color:white;box-shadow:0 4px 10px 0 rgba(0,0,0,0.11);overflow:hidden}.floating-window .toolbar{position:absolute;bottom:0;height:68px;width:100%;border-radius:0 0 25px 25px;background-color:#EAEAEA;display:flex;flex-direction:row-reverse;padding:6px;padding-right:20px}.floating-window .toolbar .svg{display:inline-block;padding-right:10px}.floating-window .toolbar .back{position:absolute;top:8px;left:20px;background:none;color:#848484;box-shadow:none !important}.floating-window .toolbar button{width:126px;border-radius:15px;margin:0;margin-right:6px;margin-top:2px;margin-bottom:2px;box-shadow:0 0 10px 0 rgba(0,0,0,0.1);transition:0.1s;color:white}.floating-window .toolbar button:hover{box-shadow:0 0 6px 0 rgba(0,0,0,0.3)}.floating-window .toolbar button:active{box-shadow:0 0 2px 0 rgba(0,0,0,0.5);color:#CCC}.floating-window .full-width{padding:40px 60px !important}.floating-window .content{padding:20px;height:720px;overflow:auto}.floating-window .content p{font-size:18px;line-height:25px}.floating-window .content .column{padding:20px 40px;float:left;width:50%}.floating-window .content:after{content:\"\";display:block;clear:both;height:80px}.floating-window .content .divider{position:absolute;top:0;left:50%;height:100%;width:1px;background-color:#B7B7B7}\n\n","// https://coolors.co/e2dbbe-9aa899-1a1423-66666e-9999a1\r\n\r\n@import 'colors';\r\n@import url('https://fonts.googleapis.com/css2?family=Heebo:wght@400;500;800&family=Open+Sans:ital,wght@0,300;0,400;0,700;1,400&display=swap');\r\n\r\n* , *:before, *:after{ \r\n box-sizing:border-box; \r\n -moz-box-sizing:border-box; \r\n -webkit-box-sizing:border-box; \r\n -ms-box-sizing:border-box;\r\n}\r\n\r\nbody {\r\n font-family: 'Open Sans', sans-serif;\r\n -webkit-font-smoothing: antialiased;\r\n -moz-osx-font-smoothing: grayscale;\r\n}\r\n\r\nh1,h2,h3,h4,h5,h6 {\r\n font-family: 'Heebo', sans-serif;\r\n margin: 0;\r\n}\r\np {\r\n margin: 0;\r\n}\r\nh1 {\r\n font-size: 42px;\r\n line-height: 62px;\r\n}\r\n\r\ncode {\r\n font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',\r\n monospace;\r\n}\r\n"]} \ No newline at end of file diff --git a/static/js/main.f79f5540.chunk.js b/static/js/main.70ebaa88.chunk.js similarity index 99% rename from static/js/main.f79f5540.chunk.js rename to static/js/main.70ebaa88.chunk.js index 0c994de..9498273 100644 --- a/static/js/main.f79f5540.chunk.js +++ b/static/js/main.70ebaa88.chunk.js @@ -1,2 +1,2 @@ (this["webpackJsonpexistential-graphs"]=this["webpackJsonpexistential-graphs"]||[]).push([[0],{12:function(e){e.exports=JSON.parse('{"binary":{"<->":"\\\\leftrightarrow","%":"\\\\leftrightarrow","->":"\\\\rightarrow","$":"\\\\rightarrow","&":"\\\\land","|":"\\\\lor"},"unary":{"~":"\\\\lnot","!":"\\\\lnot"},"eg":{"<->":"($1($2))(($1)$2)","%":"($1($2))(($1)$2)","->":"(($1)$2)","$":"(($1)$2)","&":"$1$2","|":"(($1)($2))"}}')},23:function(e,t,n){e.exports=n(64)},28:function(e,t,n){},29:function(e,t,n){},33:function(e,t,n){},62:function(e,t,n){},63:function(e,t,n){},64:function(e,t,n){"use strict";n.r(t);var a=n(0),r=n.n(a),i=n(10),s=n.n(i),o=(n(28),n(3)),c=n(4),l=n(1),u=n(6),h=n(5),d=(n(29),n(12)),v=d.binary,p=d.unary;function f(e){return"(?:"+(e=e.map((function(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}))).join("|")+")"}var g=f(Object.keys(p)),m="^(".concat(g,"*[A-Za-z]+|").concat(g,"*\\((.*)\\))(").concat(f(Object.keys(v)),")(").concat(g,"*[A-Za-z]+|").concat(g,"*\\((.*)\\))$"),b=new RegExp(m),y=new RegExp("^".concat(g,"*[A-Za-z]+$")),E=new RegExp("^".concat(g,"*\\((.*)\\)$"));var S=function(e){return function e(t){var n;return!!t.match(y)||(null!==(n=b.exec(t))?null!=n&&(n[2]&&n[5]?e(n[2])&&e(n[5]):n[2]?e(n[2]):!n[5]||e(n[5])):null!==(n=E.exec(t))?e(n[1]):void 0)}(e=e.replace(/\s/g,""))},k=n(12);function C(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var w=k.binary,O=Object.keys(w);O=O.map((function(e){return C(e)}));var j=new RegExp("(?:"+O.join("|")+")","g"),x=k.unary;function N(e){var t=function(e){return function(t){return t===e}},n=0;for(n in e.split(""))if(!Object.keys(x).some(t(e.charAt(n))))break;return n}var P=function(e,t){null==t&&(t=!0);var n=N(e),a=e.substr(n);return a=t?D(a):"{"+a+"}","(".repeat(n)+a+")".repeat(n)},D=function e(t){if(("string"===typeof t||t instanceof String)&&S(t)){t=t.replace(/\s/g,"");var n=b.exec(t),a=E.exec(t),r=y.exec(t);if(n){var i=e(n[1]),s=e(n[4]);return k.eg[n[3]].replace(/\$1/g,i).replace(/\$2/g,s)}return a?0!=N(t)?P(t):e(a[1]):r?P(t,!1):null}return null},z=function(e,t){for(var n=0,a=t;a-1&&(o.data.splice(c,1),a+=1,n.push(i),this.setState({steps:n,currentStep:a,data:r}),!0)}},{key:"doubleCutAdd",value:function(e){var t=this.state,n=t.steps,a=t.currentStep,r=t.data,i=this.copyStep(n[a]),s=this.findID(i,e);if(!s)return!1;var o=T(),c=T(),l={data:[{data:[s],id:c,type:"cut"}],id:o,type:"cut"},u=r[e].level;r[c]={type:"cut",level:u+1},r[o]={type:"cut",level:u},this.changeCutLevel(i,e,2);var h=this.findParent(i,e);if(!h)return!1;var d=h.data.indexOf(s);return d>-1&&h.data.splice(d,1),h.data=h.data.concat(l),a+=1,n.push(i),this.setState({steps:n,currentStep:a,data:r}),!0}},{key:"doubleCutRemove",value:function(e){var t=this.state,n=t.steps,a=t.currentStep,r=t.data,i=this.copyStep(n[a]),s=this.findID(i,e);if(s&&"cut"===s.type){var o=s.data;if(o&&1===o.length&&"cut"===o[0].type){var c=o[0].data,l=this.findParent(i,e);if(!l)return!1;this.changeCutLevel(i,o[0].id,-2);var u=l.data.indexOf(s);return u>-1&&l.data.splice(u,1),l.data=l.data.concat(c),a+=1,n.push(i),this.setState({steps:n,currentStep:a,data:r}),!0}return!1}return!1}},{key:"isInNestedGraph",value:function(e,t,n){var a=this.findParent(e,n);return a?!!this.findID(a,t)||(console.log("Child is not in nested graph of Parent"),!1):(console.log("Parent Data could not be found"),!1)}},{key:"copyContents",value:function(e){var t=this.state.data;function n(e,n){var r={};for(var i in e)if("id"===i){var s=T();r[i]=s,t[s]={type:"cut",level:n}}else r[i]="data"!==i?e[i]:a(e[i],n+1);return r}function a(e,a){var r=[];for(var i in e)if("string"===typeof e[i]){var s=T();r.push(s),t[s]={type:"var",var:t[e[i]].var,x:t[e[i]].x,y:t[e[i]].y}}else r.push(n(e[i],a));return r}var r=n(e,0);return this.setState({data:t}),r}},{key:"changeCutLevel",value:function(e,t,n){var a=this.state.data;if("var"!==a[t].type){var r=!1;s(e.data),this.setState({data:a})}else a[t].level+=n;function i(e){var i;e.id&&(i=e.id)===t&&(r=!0),r&&(a[i].level+=n),e.data&&s(e.data)}function s(e){for(var t in e)"string"!==typeof e[t]?i(e[t]):r&&(a[e[t]].level+=n)}}},{key:"copyStep",value:function(e){var t={};function n(e){var t={};for(var n in e)"string"===typeof e[n]?t[n]=e[n]:t[n]=a(e[n]);return t}function a(e){var t=[];for(var a in e)"string"===typeof e[a]?t.push(e[a]):t.push(n(e[a]));return t}return t.data=a(e.data),t.h=e.h,t.w=e.w,t}},{key:"findParent",value:function(e,t){var n=e;function a(e){for(var n in e)if("string"===typeof e[n]){if(e[n]===t)return!0}else{if(e[n].id&&e[n].id===t)return!0;r(e[n])}return!1}function r(e){e.data&&a(e.data)&&(n=e)}return a(e.data),n}},{key:"findID",value:function(e,t){function n(e){for(var n in e)if("string"===typeof e[n]){if(e[n]===t)return t}else{if(e[n].id===t)return e[n];var r=a(e[n]);if(r)return r}}function a(e){for(var a in e){if(e[a]instanceof Array)return n(e[a]);if("id"===a&&e[a]===t)return e}}return a(e)}},{key:"changePos",value:function(e,t,n){var a=this.state.data;Object.assign(a[e],{x:t,y:n}),this.setState(a)}},{key:"highlightCut",value:function(e){if("all"===this.state.highlights.cut)return!0;var t=!1;return e%2===1&&(t=!0),!("odd"!==this.state.highlights.cut||!t)||"even"===this.state.highlights.cut&&!t}},{key:"highlightVar",value:function(e){if("all"===this.state.highlights.var)return!0;var t=!1;return e%2===1&&(t=!0),!("odd"!==this.state.highlights.var||!t)||"even"===this.state.highlights.var&&!t}},{key:"renderStep",value:function(e){var t=this,n=this.state.data,a=this.state.steps[e];if(a){var i=function e(a){var i=[],s=function(s){if("cut"===a[s].type){var o=n[a[s].id].level,c=r.a.createElement(L,{level:o,enableHighlight:t.highlightCut(o),id:a[s].id,selectedCallback:t.state.cbFunction},e(a[s].data));i.push(c)}else{var l=t.state.data[a[s]],u=n[a[s]].level;i.unshift(r.a.createElement(M,{x:l.x,y:l.y,id:a[s],enableHighlight:t.highlightVar(u),selectedCallback:t.state.cbFunction,panzoom:t.panzoom,interaction:t.state.interaction||t.highlightVar(u),getCoords:t.getSVGCoords,setCoords:function(e,r){return function(e,a,r){n[e].x=a,n[e].y=r,t.setState({data:n})}(a[s],e,r)},key:a[s]},l.var))}};for(var o in a)s(o);return i};return i.bind(this),i(a.data)}}},{key:"componentDidMount",value:function(){this.panzoom=F()(this.canvas.current,{maxZoom:6,minZoom:.5});var e=Math.max(document.documentElement.clientWidth,window.innerWidth||0),t=Math.max(document.documentElement.clientHeight,window.innerHeight||0),n=this.state.steps;if(0===n.length){var a=this.state.proof,r=a.premises,i=(a.conclusion,function(e,t){var n={},a=0,r=0,i=0;return{stepZero:{data:function e(t,s,o){for(var c in console.log(n),t)if(t[c]instanceof Array&&t[c].length>0){var l=T();t[c]={data:e(t[c],s+1),id:l,type:"cut"},n[l]={type:"cut",level:s}}else{var u=a,h=T();n[h]={type:"var",var:t[c],x:Math.round(u/A.gridSize)*A.gridSize,y:Math.round(0/A.gridSize)*A.gridSize,level:s},t[c]=h,i=0>i?0:i,r=u>r?u:r,a+=A.initialSeparation}return t}(e,t),h:i+22,w:r},data:n}}(function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;if("string"===typeof t||t instanceof String){for(var a=[];n escapeRegExp(el));\n return '(?:' + arr.join('|') + ')'\n} \n\nconst uReg = arrToRegex(Object.keys(unary));\nconst regexStr = `^(${uReg}*[A-Za-z]+|${uReg}*\\\\((.*)\\\\))(${arrToRegex(Object.keys(binary))})(${uReg}*[A-Za-z]+|${uReg}*\\\\((.*)\\\\))$`\nlet binaryRegex = new RegExp(regexStr) // eslint-disable-line\nlet atomicRegex = new RegExp(`^${uReg}*[A-Za-z]+$`)\nlet parenthesisRegex = new RegExp(`^${uReg}*\\\\((.*)\\\\)$`)\n\nfunction verifyRecursive(sentence) {\n let res\n if (sentence.match(atomicRegex)) return true;\n else if ((res = binaryRegex.exec(sentence)) !== null) {\n if (res == null) return false;\n if (res[2] && res[5]) \n return verifyRecursive(res[2]) && verifyRecursive(res[5]);\n else if (res[2]) \n return verifyRecursive(res[2]);\n else if (res[5]) \n return verifyRecursive(res[5]);\n else return true;\n } else if ((res = parenthesisRegex.exec(sentence)) !== null)\n return verifyRecursive(res[1])\n}\n\nexport {\n binaryRegex,\n atomicRegex,\n parenthesisRegex\n}\n\nexport default (sentence) => {\n // filter out spaces\n sentence = sentence.replace(/\\s/g, '')\n return verifyRecursive(sentence);\n}","import verifySentence, { \n parenthesisRegex, \n binaryRegex,\n atomicRegex\n} from './verifySentence';\n\nconst operators = require('./operators.json')\n\nfunction escapeRegExp(string) {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n}\n\nconst binaryOperators = operators.binary\nlet keys = Object.keys(binaryOperators);\nkeys = keys.map(el => escapeRegExp(el));\nconst binarySymbReplace = new RegExp('(?:' + keys.join('|') + ')', 'g')\n\nconst unaryOperators = operators.unary\n\nconst convertToTeX = (formula) => {\n if (typeof formula === 'string' || formula instanceof String) {\n // filter out spaces\n formula = formula.replace(/\\s/g, '')\n let symbol\n // replace all binary operators\n while ((symbol = binarySymbReplace.exec(formula)) !== null) {\n formula = formula.substr(0,symbol['index']) \n + binaryOperators[symbol[0]] + ' '\n + formula.substr(symbol['index'] + symbol[0].length);\n }\n // replace all unary operators\n for (let i in Object.keys(unaryOperators)) {\n symbol = Object.keys(unaryOperators)[i];\n formula = formula.replace(new RegExp(escapeRegExp(symbol), 'g'), unaryOperators[symbol] + ' ');\n }\n // filter out all other characters\n formula = formula.replace(/[^()A-Za-z\\\\\\s]/g, '')\n return formula\n }\n else return \"\"\n}\n\nfunction countUnary(statement) {\n const matchesList = (val) => (op) => op === val;\n let c = 0;\n for (c in statement.split(\"\"))\n if (!Object.keys(unaryOperators).some(matchesList(statement.charAt(c))))\n break;\n return c;\n}\n\nconst stripUnary = (s, convertStatement) => {\n if (convertStatement == null) \n convertStatement = true;\n let c = countUnary(s);\n let statement = s.substr(c)\n if (convertStatement) statement = convertToEG(statement)\n else statement = '{' + statement + '}'\n return \"(\".repeat(c) + statement + \")\".repeat(c)\n}\n\nconst convertToEG = (formula) => {\n if ((typeof formula === 'string' || formula instanceof String) && verifySentence(formula)) {\n // filter out spaces\n formula = formula.replace(/\\s/g, '')\n let binary = binaryRegex.exec(formula)\n let parenthesis = parenthesisRegex.exec(formula)\n let unary = atomicRegex.exec(formula)\n if (binary) {\n let left = convertToEG(binary[1])\n let right = convertToEG(binary[4])\n let symConversion = operators.eg[binary[3]];\n return symConversion.replace(/\\$1/g, left).replace(/\\$2/g, right)\n } else if (parenthesis) {\n if (countUnary(formula) != 0) {\n return stripUnary(formula)\n }\n return convertToEG(parenthesis[1]);\n } else if (unary) {\n return stripUnary(formula, false);\n } else return null;\n }\n else return null;\n}\n\n/* Given a string and the index of the open parenthesis, this\n * will return the index of the closed parenthesis\n */\nconst getMatchingParen = (formula, start) => {\n // hold the number of '(' minus the number of ')'\n let parens = 0\n let j = start\n while (j < formula.length) {\n if (formula[j] === '(') {\n parens++\n }\n else if (formula[j] === ')') {\n parens--\n // if parens is 0, then the current ')' matches the start parenthesis\n if (parens === 0)\n return j\n }\n j++\n }\n}\n\n/* Converts a string representing an Existential Graph into\n * a nested array. Acts recursively, calling iteslf again\n * When a pair of parentehses are found. If given an index i,\n * this will start from that index.\n * For example: \n * \"((({P})){Q}{R}){P}\" => [ [ [['P']],'Q','R' ],'P' ]\n */\nconst convertToArray = (formula, i = 0) => {\n if (typeof formula === 'string' || formula instanceof String) {\n // hold the array of the current level that will be returned\n let arr = []\n // loop through the string\n while (i < formula.length) {\n // if closing parenthesis, return the array for this subexpression\n if (formula[i] === '(') {\n // find the matching pair of parentheses of the subexpression\n let j = getMatchingParen(formula, i)\n // push the subexpression into the array\n let subExp = formula.substr(i+1, j-1)\n if (subExp)\n arr.push(convertToArray(formula.substr(i+1, j-1)))\n i = j\n }\n // if a variable is found, push it to the array\n else if (formula[i] === '{') {\n let text = formula[++i];\n if (text === '}') arr.push('\\u00A0')\n else arr.push(text)\n i++\n }\n i++\n }\n // return the array that values the current expression\n return arr\n }\n else return null\n}\n\nexport {\n convertToTeX,\n convertToEG,\n convertToArray,\n verifySentence\n}","import React from 'react';\n\nclass Toolbox extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n functions: [\n {\n str: \"Iterate/Deiterate\",\n func: 'iterate',\n highlight: { 'cut': 'all', 'var': 'all' }\n },\n {\n str: \"Remove Double Cut\",\n func: 'dcRemove',\n highlight: { 'cut': 'all' }\n },\n {\n str: \"Add Double Cut\",\n func: 'dcAdd',\n highlight: { 'cut': 'all', 'var': 'all' }\n },\n {\n str: \"Insertion\",\n func: 'insert',\n highlight: { 'cut': 'odd', 'var': 'odd' }\n },\n {\n str: \"Erasure\",\n func: 'erase',\n highlight: { 'cut': 'even', 'var': 'even' }\n }\n ]\n };\n }\n\n componentDidMount() { \n }\n\n render() {\n if (this.props.hidden) return ;\n return (\n
\n

Tools

\n {this.state.functions.map(el => (\n
this.props.setSelection(el.highlight, el.func)}>{el.str}
\n ))}\n
\n );\n }\n}\n\nexport default Toolbox;","import React from 'react';\nimport { ReactSVG } from 'react-svg';\n\nclass StepMenu extends React.Component {\n handleClick(event, step, disabled) {\n event.preventDefault();\n if (!disabled) {\n // Must update color before updating props to allow component to\n // render with the proper current color rather than the state before\n this.props.setStep(step);\n }\n }\n\n getColor(disabled) {\n return disabled ? \"rgb(136, 136, 136)\" : \"rgb(68, 68, 68)\";\n }\n\n render() {\n let { hide, currentStep, stepInfo } = this.props;\n if (hide) return ();\n let backEnabled = currentStep === (stepInfo.length - 1);\n let forwardEnabled = currentStep === 0;\n return (\n \n
\n
\n
this.handleClick(event, 0, forwardEnabled)}>\n \n
\n
this.handleClick(event, currentStep - 1, forwardEnabled)}>\n \n
\n
\n
\n
this.handleClick(event, currentStep + 1, backEnabled)}>\n \n
\n
this.handleClick(event, stepInfo.length - 1, backEnabled)}>\n \n
\n
\n
\n
\n Step {currentStep + 1} of {stepInfo.length}\n
\n
\n );\n }\n}\n\nexport default StepMenu;","export default {\n gridSize: 1,\n cutPadding: {\n horizontal: 10,\n vertical: 5\n },\n cutCornerRadius: 10,\n initialSeparation: 50,\n}","import React from 'react';\nimport config from './config';\n\nclass EGVariable extends React.Component {\n constructor(props) {\n super(props);\n this.text = React.createRef()\n this.getCoords = this.props.getCoords\n this.handleClick = this.handleClick.bind(this);\n this.state = {\n x: props.x,\n y: props.y,\n cursorOver: false,\n dragging: false\n };\n\n this.panzoom = this.props.panzoom\n\n window.addEventListener('mousemove', this.onMouseMove.bind(this))\n window.addEventListener('mousedown', this.handleDragStart.bind(this))\n window.addEventListener('mouseup', this.handleDragEnd.bind(this))\n window.addEventListener('click', this.handleClick)\n }\n\n handleClick() {\n if (this.state.cursorOver \n && this.props.enableHighlight \n && this.props.selectedCallback) \n {\n this.props.selectedCallback(this.props.id);\n this.setState({ cursorOver: false });\n }\n }\n\n componentDidMount() { \n this.text.current.style.cursor = \"pointer\";\n }\n\n handleDragStart(evt) {\n if (this.state.cursorOver) {\n this.panzoom.pause()\n this.setState({ dragging: true })\n }\n }\n\n handleDragEnd(evt) {\n this.panzoom.resume()\n let { x, y } = this.state;\n this.props.setCoords(x, y);\n this.setState({ dragging: false })\n }\n\n onMouseMove(evt) {\n if (this.state.dragging) {\n let { x, y } = this.getCoords(evt.clientX, evt.clientY)\n x = Math.round(x/config.gridSize)*config.gridSize\n y = Math.round(y/config.gridSize)*config.gridSize\n this.props.setCoords(x, y);\n this.setState({ x: x, y: y })\n }\n }\n\n componentWillUnmount() {\n window.removeEventListener('click', this.handleClick);\n window.removeEventListener('mousemove', this.onMouseMove.bind(this))\n window.removeEventListener('mousedown', this.handleDragStart.bind(this))\n window.removeEventListener('mouseup', this.handleDragEnd.bind(this))\n }\n\n render() {\n let highlight = this.state.cursorOver && this.props.enableHighlight;\n return (\n this.setState({ cursorOver: true })}\n onMouseLeave={() => this.setState({ cursorOver: false })}\n ref={this.text}>\n {this.props.children}\n \n );\n }\n}\n\nexport default EGVariable;","import React from 'react';\nimport config from './config';\n\nclass EGCut extends React.Component {\n constructor(props) {\n super(props);\n this.cut = React.createRef();\n this.BB = React.createRef();\n this.getBBoxData = this.getBBoxData.bind(this);\n this.handleClick = this.handleClick.bind(this);\n this.update = this.update.bind(this);\n this.state = { highlight: false, bounding: {_x:0,_y:0,_w:0,_h:0} };\n\n window.addEventListener('click', this.handleClick)\n }\n\n handleClick() {\n if (this.state.highlight \n && this.props.enableHighlight \n && this.props.selectedCallback) \n {\n this.props.selectedCallback(this.props.id);\n this.setState({ highlight: false });\n }\n }\n\n getBBoxData() {\n if (this.cut.current) {\n let { x, y, width, height } = this.cut.current.getBBox();\n let _x = x - config.cutPadding.horizontal;\n let _y = y - config.cutPadding.vertical;\n let _w = width + config.cutPadding.horizontal * 2;\n let _h = height + config.cutPadding.vertical * 2;\n return { _x, _y, _w, _h };\n }\n return {};\n }\n\n update() {\n if (!this.interval) {\n this.interval = setInterval(() => {\n this.setState({ bounding: this.getBBoxData() });\n }, 1);\n setTimeout(() => {\n clearInterval(this.interval);\n this.interval = null;\n }, 100);\n }\n }\n\n componentDidMount() { \n this.update()\n }\n\n componentDidUpdate() {\n this.update()\n }\n\n componentWillUnmount() {\n window.removeEventListener('click', this.handleClick);\n if (this.interval)\n clearInterval(this.interval);\n }\n\n render() {\n let childEl = this.props.children;\n if (childEl.length < 1) {\n childEl = {\" \"}\n }\n let highlight = this.state.highlight && this.props.enableHighlight;\n let { _x, _y, _w, _h } = this.state.bounding;\n return (\n \n this.setState({ highlight: true })}\n onMouseLeave={() => this.setState({ highlight: false })}\n rx={config.cutCornerRadius.toString()} \n ry={config.cutCornerRadius.toString()}\n />\n \n {this.props.children}\n \n \n );\n }\n}\n\nexport default EGCut;","import React from 'react';\nimport { convertToArray } from '../converters';\nimport Toolbox from './Toolbox';\nimport StepMenu from './StepMenu';\nimport EGVariable from './EGVariable';\nimport EGCut from './EGCut';\nimport './Canvas.scss';\nimport Panzoom from 'panzoom';\nimport config from './config';\nimport { NotificationContainer, NotificationManager } from 'react-notifications';\nconst nanoid = require('nanoid').nanoid;\n\n// some defaults: \n// blocks are automatically 22px high\n\nconst TEXT_H = 22;\n\nfunction initXY(step, level) {\n let data = {}\n let currentX = 0\n let currentY = 0\n let maxX = 0\n let maxY = 0\n\n // gapSize should be equal to the number of level changes\n // in between two variables, so that we can evenly place \n // them initially across the screen\n function initXYRecurse(step, level, gapSize) {\n console.log(data)\n for (let s in step) {\n if (step[s] instanceof Array && step[s].length > 0) {\n let id = nanoid()\n step[s] = { data: initXYRecurse(step[s], level + 1), id: id, type: \"cut\" }\n data[id] = { type: \"cut\", level: level }\n } else {\n let X = currentX;\n let Y = currentY;\n let id = nanoid()\n data[id] = { \n type: \"var\",\n var: step[s], \n x: Math.round(X/config.gridSize)*config.gridSize, \n y: Math.round(Y/config.gridSize)*config.gridSize,\n level: level\n }\n step[s] = id\n maxY = Y > maxY ? Y : maxY;\n maxX = X > maxX ? X : maxX;\n currentX += config.initialSeparation\n }\n }\n return step\n }\n return { stepZero: { data: initXYRecurse(step, level), h: maxY + TEXT_H, w: maxX }, data: data }\n}\n\nclass Canvas extends React.Component {\n constructor(props) {\n super(props);\n this.canvas = React.createRef();\n this.canvasContainer = React.createRef();\n\n this.renderStep = this.renderStep.bind(this);\n this.changePos = this.changePos.bind(this);\n this.getSVGCoords = this.getSVGCoords.bind(this);\n this.highlightCut = this.highlightCut.bind(this);\n this.startSelection = this.startSelection.bind(this);\n\n let { premises, conclusion, steps, data } = this.props.proof;\n this.state = {\n proof: {\n premises: premises,\n conclusion: conclusion\n },\n steps: steps || [],\n data: data || {},\n currentStep: 0,\n moveListeners: [],\n highlights: {\n cut: 'none', // 'none', 'odd', 'even', 'all'\n var: 'none'\n },\n cbFunction: null,\n interaction: true,\n functions: {\n insert: (id) => {\n console.log(\"INSERTION\")\n },\n erase: (id) => {\n console.log(\"ERASURE\")\n return this.erasure(id);\n },\n iterate: (id) => {\n console.log(\"ITERATION\")\n return this.iteration(id, this.state.steps[this.state.currentStep].data[0].id);\n },\n dcRemove: (id) => {\n console.log(\"DOUBLE CUT Remove\")\n return this.doubleCutRemove(id);\n },\n dcAdd: (id) => {\n console.log(\"DOUBLE CUT Add\")\n return this.doubleCutAdd(id);\n \n }\n }\n }\n }\n\n startSelection(selectable, nameOfFunction) {\n let { steps, currentStep } = this.state;\n // only allow steps to be conducted at the end of a proof\n if (currentStep+1 !== steps.length) {\n return\n }\n this.setState({ \n highlights: selectable, \n interaction: false, \n cbFunction: (id) => {\n let successful = this.state.functions[nameOfFunction](id); \n if (successful) \n this.setState({ \n highlights: {\n cut: 'none', \n var: 'none'\n },\n interaction: true, \n cbFunction: null });\n }\n });\n }\n\n /* Given a copyID and insertID, the iteration function creates a new step,\n * and adds a copy of the data represented by copyID at the location of insertID\n * only if the location of insertID is a child of copyID\n */\n iteration(copyID, insertID) {\n let { steps, currentStep, data } = this.state;\n let step = this.copyStep(steps[currentStep]);\n // If the insertID data is not in a subgraph of the copID data, return\n if (!this.isInNestedGraph(step, insertID, copyID)) {\n console.log(\"Insert selection is not in a subgraph of Copy selection\");\n return false;\n }\n // use findID to find the data represented by the two IDs\n let copy = this.copyContents(this.findID(step, copyID));\n if (!copy) {\n console.log(\"Copy ID could not be found in Iterate\");\n return false;\n }\n let insert = this.findID(step, insertID);\n if (!insert) {\n console.log(\"Insert ID could not be found in Iterate\");\n return false;\n }\n insert.data = insert.data.concat(copy);\n // Change the levels of the copy data\n this.changeCutLevel(step, copy.id, data[insert.id].level + 1)\n // Update the state\n currentStep+=1;\n steps.push(step);\n this.setState({ steps: steps, currentStep: currentStep, data:data });\n return true;\n }\n\n erasure(id) {\n let { steps, currentStep, data } = this.state;\n // Create a new step\n let step = this.copyStep(steps[currentStep]);\n // Find the data that will be erased\n let erased = this.findID(step, id);\n if (!erased) {\n return false;\n }\n // Get the parent of the erased section\n let parent = this.findParent(step, id)\n if (!parent) {\n return false;\n }\n // Remove the erased data from the parent's data array\n const index = parent.data.indexOf(erased);\n if (index > -1)\n parent.data.splice(index, 1);\n else {\n return false;\n }\n // Update the state\n currentStep+=1;\n steps.push(step);\n this.setState({ steps: steps, currentStep: currentStep, data:data });\n return true;\n }\n\n /* Adds a double cut given the ID of the data that will be inside the cut.\n * Will only run if the current step is the last step.\n */\n doubleCutAdd(ID) {\n let { steps, currentStep, data } = this.state;\n // create a new step\n let step = this.copyStep(steps[currentStep]);\n // use findID to find the data represented by the id\n // this is the data that will be inside the two new cuts\n let inside = this.findID(step, ID);\n if (!inside) {\n return false;\n }\n // create a new cut with another one inside it\n let cut1_id = nanoid();\n let cut2_id = nanoid();\n let cut2 = {\n data: [inside],\n id: cut2_id,\n type: \"cut\"\n }\n let cut1 = {\n data: [cut2],\n id: cut1_id,\n type: \"cut\"\n }\n // Set the levels of the two cuts\n let level = data[ID].level\n data[cut2_id] = { type: \"cut\", level: level + 1};\n data[cut1_id] = { type: \"cut\", level: level};\n // increase the level of the inside cut along with all cuts inside of it by 2\n this.changeCutLevel(step, ID, 2)\n\n // get the parent of the selection\n let parent = this.findParent(step, ID)\n if (!parent) {\n return false;\n }\n // Add the contents of the new cuts to the data array\n // after removing the original contents\n const index = parent.data.indexOf(inside);\n if (index > -1) {\n parent.data.splice(index, 1);\n }\n parent.data = parent.data.concat(cut1);\n // Change the state data accordingly\n currentStep+=1;\n steps.push(step);\n this.setState({ steps: steps, currentStep: currentStep, data:data });\n return true;\n }\n\n /* Removes a double cut given the ID of the outside cut.\n * Will only run if the current step is the last step.\n * Creates a deep copy of the current step, and replaces the cut with\n * the given ID with the contents of the second cut, only if they exist.\n * Then adds the edited copy of the current step to the end of the step array.\n */\n doubleCutRemove(cutID) {\n let { steps, currentStep, data } = this.state;\n // Create a new step\n let step = this.copyStep(steps[currentStep]);\n\n // use findID to find the cut with the given ID\n let firstCut = this.findID(step, cutID);\n // If it is actually a cut and has another cut inside\n if (firstCut && firstCut.type === \"cut\") {\n let secondCut = firstCut.data;\n if (secondCut && secondCut.length === 1 && secondCut[0].type === \"cut\") {\n // Get the data inside the second cut\n let newContents = secondCut[0].data;\n // Get the parent of the original cut being removed\n let parent = this.findParent(step, cutID)\n if (!parent) {\n return false;\n }\n this.changeCutLevel(step, secondCut[0].id, -2)\n // Remove the first cut from the data array\n const index = parent.data.indexOf(firstCut);\n if (index > -1) {\n parent.data.splice(index, 1);\n }\n // Add the contents of the second cut to the data array\n parent.data = parent.data.concat(newContents);\n // Update the state\n currentStep+=1;\n steps.push(step);\n this.setState({ steps: steps, currentStep: currentStep, data:data });\n return true;\n }\n else return false;\n }\n else return false;\n }\n\n\n /* Given a step and two IDs, will return true if the data of ChildID is\n * in a nested graph of parentID in the current step.\n */\n isInNestedGraph(step, childID, parentID) {\n let parentStep = this.findParent(step, parentID);\n if (!parentStep) {\n console.log(\"Parent Data could not be found\");\n return false;\n }\n let childStep = this.findID(parentStep, childID);\n if (!childStep) {\n console.log(\"Child is not in nested graph of Parent\");\n return false;\n }\n return true;\n }\n\n /* Given a step or a cut, will copy the contents inside with new IDs\n * and return the new data. This permits inserting new data into the graph.\n * Levels for cuts will start at 0 and increase accordingly\n */\n copyContents(step) {\n let { data } = this.state;\n // Copies the data of a map and returns it\n // Also updates the state.data map according to new generated IDs\n function copyDataMap(map, level) {\n let newMap = {};\n for (let m in map) {\n // If an ID is found, generate a new one\n if (m === 'id') {\n let id = nanoid();\n newMap[m] = id;\n // Add the new data to state.data via a deep copy\n data[id] = {\n type: \"cut\",\n level: level\n }\n }\n // Otherwise, if not a data array, copy the contents\n else if (m !== 'data'){\n newMap[m] = map[m]\n }\n // If a data array, copy using helper function\n else {\n newMap[m] = copyDataArray(map[m], level+1)\n }\n }\n return newMap;\n }\n // Copies the data of an array and returns it\n // Also updates state.data according to new generated IDs\n function copyDataArray(arr, level) {\n let newArr = [];\n for (let a in arr) {\n // If an ID found, generate a new one\n if (typeof arr[a] === 'string') {\n let id = nanoid();\n newArr.push(id);\n // Add the new data to state.data via a deep copy\n data[id] = {\n type: \"var\",\n var: data[arr[a]].var,\n x: data[arr[a]].x,\n y: data[arr[a]].y,\n }\n }\n // otherwise, call the other helper function to copy contents\n else {\n newArr.push(copyDataMap(arr[a], level))\n }\n }\n return newArr;\n }\n let newStep = copyDataMap(step, 0);\n this.setState({ data: data })\n return newStep;\n }\n\n /* Given a step and the ID of a cut, will iterate through all cuts within\n * that cut and change their level by a specified amount.\n */\n changeCutLevel(step, id, change) {\n let { data } = this.state\n // If the ID is for a variable, only increase it's level\n if (data[id].type === \"var\") {\n data[id].level += change;\n return\n }\n // when true, the levels should change in the functions below\n let idFound = false\n // Changes the \n function changeLevelMap(map) {\n // get the id for the current map\n let mapID;\n if (map.id) {\n mapID = map.id\n // if it matches the id being searched, update the boolean\n if (mapID === id) {\n idFound = true;\n }\n }\n // If the ID has been found, update the level of the current cut\n if (idFound) {\n data[mapID].level += change;\n }\n // call the function of the data array if it exists\n if (map.data){\n changeLevelArray(map.data);\n }\n }\n function changeLevelArray(arr) {\n for (let a in arr) {\n // If a non-string is found (a cut)\n if (typeof arr[a] !== 'string') {\n // Change the level of the cut\n changeLevelMap(arr[a])\n }\n // If string is found, change the level of the variable\n else if (idFound){\n data[arr[a]].level += change;\n }\n }\n }\n changeLevelArray(step.data)\n this.setState({ data: data })\n }\n\n // Performs a deep copy of oldStep into newStep, used to not change previous steps\n // By allowing them to be copied without using a reference\n copyStep(oldStep) {\n let newStep = {};\n function copyDataMap(oldData) {\n let newData = {};\n for (let d in oldData) {\n // If an id or type if found, copy directly\n if(typeof oldData[d] === 'string') {\n newData[d] = oldData[d];\n }\n // Otherwise if an array is found, copy using helper function\n else {\n newData[d] = copyDataArray(oldData[d]);\n }\n }\n return newData;\n }\n function copyDataArray(oldData) {\n let newData = [];\n for (let d in oldData) {\n // If an ID is found (variable), copy directly\n if(typeof oldData[d] === 'string') {\n newData.push(oldData[d]);\n }\n // If a map was found (cut), copy using helper function\n else {\n newData.push(copyDataMap(oldData[d]));\n }\n }\n return newData;\n }\n // Copy the data, width, and height of the original into the new step\n newStep.data = copyDataArray(oldStep.data);\n newStep.h = oldStep.h;\n newStep.w = oldStep.w;\n return newStep;\n }\n\n /* Finds and returns the item that is the parent of the item\n * with the specified ID, given the step to search as well.\n */\n findParent(searchedStep, id) {\n // holds the parent of the id\n let parent = searchedStep\n // Searches an array for the ID, returns true if it is found\n function findInArray(arr) {\n for (let a in arr) {\n // If an ID is found, compare it\n if (typeof arr[a] === 'string') {\n if (arr[a] === id) {\n return true;\n }\n }\n // Otherwise if a datamap is found, check the ID\n else {\n // If ID matches, return true\n if (arr[a].id && arr[a].id === id) {\n return true;\n }\n // Otherwise, search the datamap\n else {\n findInMap(arr[a])\n }\n }\n }\n return false;\n }\n function findInMap(map) {\n // if the map contains data, search the data\n if (map.data) {\n // if found, set parent to this map\n if(findInArray(map.data)) {\n parent = map;\n }\n }\n }\n findInArray(searchedStep.data);\n return parent;\n }\n\n // finds and returns the item with the specified ID in a given step\n findID(searchedStep, id) {\n // Find the ID in an array\n function findIDArray(arr) {\n for (let a in arr) {\n // if a string, aka an ID\n if (typeof arr[a] === 'string') {\n // return the ID if found\n if (arr[a] === id) {\n return id;\n }\n }\n // if a data map is found with the correct id, return the data map\n else if (arr[a].id === id) {\n return arr[a];\n // otherwise, call findID step on the datamap that has the incorrect ID\n } else {\n let s = findIDMap(arr[a]);\n if (s)\n return s;\n }\n }\n }\n // Finds the ID in a data map representing a step\n function findIDMap(step) {\n for (let s in step) {\n // if an array is found, call findIDArray on each element\n if (step[s] instanceof Array) {\n return findIDArray(step[s]);\n // if an id is found, check if it matches and return the data if so\n } else if (s === \"id\") {\n if (step[s] === id)\n return step;\n }\n }\n }\n return findIDMap(searchedStep);\n }\n\n changePos(id, x, y) {\n let { data } = this.state;\n Object.assign(data[id], { x: x, y: y })\n this.setState(data)\n }\n\n highlightCut(level) {\n if (this.state.highlights.cut === 'all') return true;\n let odd = false;\n if (level % 2 === 1) odd = true;\n if (this.state.highlights.cut === 'odd' && odd) return true;\n else if (this.state.highlights.cut === 'even' && !odd) return true;\n return false;\n }\n\n highlightVar(level) {\n if (this.state.highlights.var === 'all') return true;\n let odd = false;\n if (level % 2 === 1) odd = true;\n if (this.state.highlights.var === 'odd' && odd) return true;\n else if (this.state.highlights.var === 'even' && !odd) return true;\n return false;\n }\n\n renderStep(stepIndex) {\n let { data } = this.state;\n let step = this.state.steps[stepIndex]\n if (step) {\n const setXY = (id,x,y) => {\n data[id].x = x;\n data[id].y = y;\n this.setState({ data: data })\n }\n\n const renderRecurse = (step) => {\n let jsx = [];\n for (let s in step) {\n if (step[s].type === \"cut\") {\n let level = data[step[s].id].level;\n let groupElement = (\n \n {renderRecurse(step[s].data)}\n \n );\n jsx.push(groupElement);\n } else {\n let el = this.state.data[step[s]];\n let level = data[step[s]].level;\n jsx.unshift(\n setXY(step[s],x,y)}\n key={step[s]}>\n {el.var}\n \n );\n }\n }\n return jsx;\n }\n renderRecurse.bind(this);\n return renderRecurse(step.data)\n }\n }\n\n componentDidMount() { \n this.panzoom = Panzoom(this.canvas.current, {\n maxZoom: 6,\n minZoom: 0.5\n });\n // this.canvasContainer.current.addEventListener('wheel', this.panzoom.zoomWithWheel);\n const vw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);\n const vh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);\n // if there are no existing steps, init first step\n let { steps } = this.state;\n if (steps.length === 0) {\n let { premises, conclusion } = this.state.proof;\n let { stepZero, data } = initXY(convertToArray(premises.join('')), 0);\n steps.push(stepZero);\n this.setState({ steps: steps, data: data });\n }\n // required to use setState to trigger re-render after creation of panzoom\n this.setState({ currentStep: 0 });\n let step = this.state.steps[this.state.currentStep];\n\n this.panzoom.moveTo(vw/2 - step.w, vh/2 - step.h);\n this.panzoom.zoomTo(vw/2 - step.w, vh/2 - step.h, 2);\n }\n\n componentWillUnmount() {\n window.removeEventListener('resize', this);\n }\n\n getSVGCoords(domX, domY) {\n var pt = this.canvasContainer.current.createSVGPoint();\n\n pt.x = domX;\n pt.y = domY;\n\n return pt.matrixTransform(this.canvas.current.getScreenCTM().inverse());\n }\n\n render() {\n let zoomWithWheel = () => {}\n let { steps, currentStep } = this.state;\n if (this.panzoom)\n zoomWithWheel = this.panzoom.zoomWithWheel\n return (\n
\n
\n );\n }\n}\n\nexport default Canvas;\n","import React from 'react';\nimport verify from '../verifySentence';\nimport { convertToTeX, convertToEG } from '../converters';\n// KATEX\nimport 'katex/dist/katex.min.css';\nimport TeX from '@matejmazur/react-katex';\nimport './CreateNew.scss';\n\nclass CreateNew extends React.Component {\n constructor(props) {\n super(props);\n \n this.state = {\n premises: [\n ''\n ],\n conclusion: ''\n };\n\n this.handleChange.bind(this)\n this.removePremise.bind(this)\n this.verify = this.verify.bind(this)\n this.create = this.create.bind(this)\n }\n\n componentDidMount() {\n\n }\n\n handleChange(e, i) {\n if (i != null) {\n let { premises } = this.state;\n premises[i] = e.target.value;\n this.setState({ premises: premises })\n }\n else this.setState({ conclusion: e.target.value })\n }\n\n removePremise(index) {\n let { premises } = this.state;\n premises.splice(index, 1);\n this.setState({ premises: premises })\n }\n\n verify() {\n let { premises, conclusion } = this.state;\n for (let i in premises) {\n if (premises[i] === '' || !premises[i])\n return false;\n }\n if (conclusion === '' || !conclusion)\n return false;\n return true;\n }\n\n create() {\n console.log(\"Creating...\")\n console.log(\"Verification concluded \" + this.verify())\n if (this.verify()) {\n let { premises, conclusion } = this.state;\n for (let i in premises) {\n premises[i] = convertToEG(premises[i])\n console.log(premises[i])\n }\n conclusion = convertToEG(conclusion)\n this.props.setupFunc(premises, conclusion, [])\n }\n }\n\n getFormulaCell(formula, i) {\n let tex, eg\n if (verify(formula)) {\n tex = convertToTeX(formula);\n eg = convertToEG(formula);\n }\n let closeBtn = this.removePremise(i)}>\n ✕\n ;\n let formulaInput = this.handleChange(e,i) } />;\n if (i == null) {\n formulaInput = this.handleChange(e) } />;\n closeBtn = ;\n }\n if (i === 0) \n closeBtn = ;\n return (\n \n \n {formulaInput}\n \n \n {tex && }\n \n \n {eg && }\n \n { closeBtn }\n \n );\n }\n\n render() {\n let { premises, conclusion } = this.state;\n return (\n
\n

Create New

\n

File Name

\n \n \n \n
\n

Premises

\n \n \n \n \n {premises.map((formula,i) => this.getFormulaCell(formula, i))}\n \n \n \n
\n Formula\n TeX notationEG notation\n
this.setState({ premises: premises.concat(['']) }) }>\n Add New Premise\n \n
\n

Conclusion

\n \n {this.getFormulaCell(conclusion)}\n
\n
\n );\n }\n}\n\nexport default CreateNew;","import React from 'react';\nimport CreateNew from './CreateNew';\nimport { ReactSVG } from 'react-svg';\nimport './intro.scss';\n\nconst IntroContent = () => (\n
\n
\n

Existential Graphs

\n

\n Using this tool, you can initialize proofs in the existential graph schema and then you can go through the process of solving them. You can save these proofs and look back at them later.\n

\n
\n
\n
\n

Recent Proofs

\n
\n
\n);\n\nclass IntroWindow extends React.Component {\n constructor(props) {\n super(props);\n this.createView = React.createRef();\n this.callCreate = this.callCreate.bind(this);\n this.animateAway = this.animateAway.bind(this);\n this.state = {\n createShown: false,\n floatingWindowCSS: 'floating-window shown'\n };\n }\n\n componentDidMount() {\n }\n\n animateAway() {\n this.setState({ floatingWindowCSS: 'floating-window' })\n }\n\n callCreate() {\n this.createView.current.create();\n }\n\n render() {\n const { createShown, floatingWindowCSS } = this.state;\n return (\n
\n {!createShown && }\n {createShown && }\n {!createShown && (\n
\n \n \n
\n )}\n {createShown && (\n
\n \n \n
\n )}\n
\n );\n }\n}\n\nexport default IntroWindow;","import React from 'react';\nimport './App.scss';\nimport Canvas from './canvas/Canvas';\nimport IntroWindow from './intro/IntroWindow';\n\nclass App extends React.Component {\n constructor(props) {\n super(props);\n \n this.createNewProof = this.createNewProof.bind(this);\n this.setupProof = this.setupProof.bind(this);\n this.openCanvas = this.openCanvas.bind(this);\n this.saveProof = this.saveProof.bind(this);\n this.introWindow = React.createRef();\n this.state = {\n initialCSS: 'initial',\n canvasOpen: false,\n popupOpen: false,\n proof: {\n premises: [],\n conclusion: '',\n steps: []\n }\n };\n // this.state = {\n // initialCSS: 'initial',\n // canvasOpen: true,\n // popupOpen: false,\n // proof: {premises: [\"({Q})(({P}){Q})\"], conclusion: \"{Q}\", steps:[] }\n // };\n }\n\n saveProof(proof) {\n this.setState({ proof: proof });\n }\n\n setupProof(premises, conclusion, steps) {\n this.setState({ \n proof: { \n premises: premises,\n conclusion: conclusion,\n steps: steps\n },\n initialCSS: 'initial whiteBG'\n });\n this.introWindow.current.animateAway();\n setTimeout(this.openCanvas, 1000);\n }\n\n openCanvas() {\n this.setState({ \n canvasOpen: true\n });\n }\n\n createNewProof() {\n this.setState({ popupOpen: true })\n }\n\n render() {\n if (this.state.canvasOpen) {\n return (\n
\n \n
\n );\n }\n return (\n
\n \n
\n );\n }\n}\n\nexport default App;\n","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n);\n\nexport function register(config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl, config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl, config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { 'Service-Worker': 'script' }\n })\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf('javascript') === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log(\n 'No internet connection found. App is running in offline mode.'\n );\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready\n .then(registration => {\n registration.unregister();\n })\n .catch(error => {\n console.error(error.message);\n });\n }\n}\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.scss';\nimport App from './App';\nimport * as serviceWorker from './serviceWorker';\n\nReactDOM.render(, document.getElementById('root'));\n\n// If you want your app to work offline and load faster, you can change\n// unregister() to register() below. Note this comes with some pitfalls.\n// Learn more about service workers: https://bit.ly/CRA-PWA\nserviceWorker.unregister();\n"],"sourceRoot":""} \ No newline at end of file diff --git a/static/js/main.f79f5540.chunk.js.map b/static/js/main.f79f5540.chunk.js.map deleted file mode 100644 index ce5d258..0000000 --- a/static/js/main.f79f5540.chunk.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["verifySentence.js","converters.js","canvas/Toolbox.js","canvas/StepMenu.js","canvas/config.js","canvas/EGVariable.js","canvas/EGCut.js","canvas/Canvas.js","intro/CreateNew.js","intro/IntroWindow.js","App.js","serviceWorker.js","index.js"],"names":["require","binary","unary","arrToRegex","arr","map","el","replace","join","uReg","Object","keys","regexStr","binaryRegex","RegExp","atomicRegex","parenthesisRegex","sentence","verifyRecursive","res","match","exec","operators","escapeRegExp","string","binaryOperators","binarySymbReplace","unaryOperators","countUnary","statement","matchesList","val","op","c","split","some","charAt","stripUnary","s","convertStatement","substr","convertToEG","repeat","formula","String","verifySentence","parenthesis","left","right","eg","getMatchingParen","start","parens","j","length","Toolbox","props","state","functions","str","func","highlight","this","hidden","Fragment","className","ref","canvas","onClick","setSelection","React","Component","StepMenu","event","step","disabled","preventDefault","setStep","hide","currentStep","stepInfo","backEnabled","forwardEnabled","style","color","getColor","handleClick","src","process","gridSize","cutPadding","horizontal","vertical","cutCornerRadius","initialSeparation","EGVariable","text","createRef","getCoords","bind","x","y","cursorOver","dragging","panzoom","window","addEventListener","onMouseMove","handleDragStart","handleDragEnd","enableHighlight","selectedCallback","id","setState","current","cursor","evt","pause","resume","setCoords","clientX","clientY","Math","round","config","removeEventListener","pointerEvents","interaction","fill","onMouseEnter","onMouseLeave","children","EGCut","cut","BB","getBBoxData","update","bounding","_x","_y","_w","_h","getBBox","width","height","interval","setInterval","setTimeout","clearInterval","childEl","fillOpacity","strokeOpacity","stroke","rx","toString","ry","nanoid","Canvas","canvasContainer","renderStep","changePos","getSVGCoords","highlightCut","startSelection","proof","premises","conclusion","steps","data","moveListeners","highlights","var","cbFunction","insert","console","log","erase","erasure","iterate","iteration","dcRemove","doubleCutRemove","dcAdd","doubleCutAdd","selectable","nameOfFunction","copyID","insertID","copyStep","isInNestedGraph","copy","copyContents","findID","concat","changeCutLevel","level","push","erased","parent","findParent","index","indexOf","splice","ID","inside","cut1_id","cut2_id","cut1","type","cutID","firstCut","secondCut","newContents","childID","parentID","parentStep","copyDataMap","newMap","m","copyDataArray","newArr","a","newStep","change","idFound","changeLevelArray","changeLevelMap","mapID","oldStep","oldData","newData","d","h","w","searchedStep","findInArray","findInMap","findIDArray","findIDMap","Array","assign","odd","stepIndex","renderRecurse","jsx","groupElement","unshift","highlightVar","setXY","key","Panzoom","maxZoom","minZoom","vw","max","document","documentElement","clientWidth","innerWidth","vh","clientHeight","innerHeight","currentX","maxX","maxY","stepZero","initXYRecurse","gapSize","X","initXY","convertToArray","i","subExp","moveTo","zoomTo","domX","domY","pt","createSVGPoint","matrixTransform","getScreenCTM","inverse","zoomWithWheel","onWheel","CreateNew","handleChange","removePremise","verify","create","e","target","value","setupFunc","tex","symbol","convertToTeX","closeBtn","formulaInput","onChange","math","getFormulaCell","IntroContent","IntroWindow","createView","callCreate","animateAway","createShown","floatingWindowCSS","App","createNewProof","setupProof","openCanvas","saveProof","introWindow","initialCSS","canvasOpen","popupOpen","Boolean","location","hostname","ReactDOM","render","getElementById","navigator","serviceWorker","ready","then","registration","unregister","catch","error","message"],"mappings":"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","file":"static/js/main.f79f5540.chunk.js","sourcesContent":["/* \r\n * Return a boolean indicating if the inputted sentence is \r\n * a correctly formatted. Utilizes a recursive technique,\r\n * evaluating each sentence as though it were an atomic\r\n * sentence or any phi and psi combined with a binary \r\n * operator. \r\n*/\r\n\r\nconst { binary, unary } = require('./operators.json')\r\n\r\nfunction escapeRegExp(string) {\r\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\r\n}\r\n\r\nfunction arrToRegex(arr) {\r\n arr = arr.map(el => escapeRegExp(el));\r\n return '(?:' + arr.join('|') + ')'\r\n} \r\n\r\nconst uReg = arrToRegex(Object.keys(unary));\r\nconst regexStr = `^(${uReg}*[A-Za-z]+|${uReg}*\\\\((.*)\\\\))(${arrToRegex(Object.keys(binary))})(${uReg}*[A-Za-z]+|${uReg}*\\\\((.*)\\\\))$`\r\nlet binaryRegex = new RegExp(regexStr) // eslint-disable-line\r\nlet atomicRegex = new RegExp(`^${uReg}*[A-Za-z]+$`)\r\nlet parenthesisRegex = new RegExp(`^${uReg}*\\\\((.*)\\\\)$`)\r\n\r\nfunction verifyRecursive(sentence) {\r\n let res\r\n if (sentence.match(atomicRegex)) return true;\r\n else if ((res = binaryRegex.exec(sentence)) !== null) {\r\n if (res == null) return false;\r\n if (res[2] && res[5]) \r\n return verifyRecursive(res[2]) && verifyRecursive(res[5]);\r\n else if (res[2]) \r\n return verifyRecursive(res[2]);\r\n else if (res[5]) \r\n return verifyRecursive(res[5]);\r\n else return true;\r\n } else if ((res = parenthesisRegex.exec(sentence)) !== null)\r\n return verifyRecursive(res[1])\r\n}\r\n\r\nexport {\r\n binaryRegex,\r\n atomicRegex,\r\n parenthesisRegex\r\n}\r\n\r\nexport default (sentence) => {\r\n // filter out spaces\r\n sentence = sentence.replace(/\\s/g, '')\r\n return verifyRecursive(sentence);\r\n}","import verifySentence, { \r\n parenthesisRegex, \r\n binaryRegex,\r\n atomicRegex\r\n} from './verifySentence';\r\n\r\nconst operators = require('./operators.json')\r\n\r\nfunction escapeRegExp(string) {\r\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\r\n}\r\n\r\nconst binaryOperators = operators.binary\r\nlet keys = Object.keys(binaryOperators);\r\nkeys = keys.map(el => escapeRegExp(el));\r\nconst binarySymbReplace = new RegExp('(?:' + keys.join('|') + ')', 'g')\r\n\r\nconst unaryOperators = operators.unary\r\n\r\nconst convertToTeX = (formula) => {\r\n if (typeof formula === 'string' || formula instanceof String) {\r\n // filter out spaces\r\n formula = formula.replace(/\\s/g, '')\r\n let symbol\r\n // replace all binary operators\r\n while ((symbol = binarySymbReplace.exec(formula)) !== null) {\r\n formula = formula.substr(0,symbol['index']) \r\n + binaryOperators[symbol[0]] + ' '\r\n + formula.substr(symbol['index'] + symbol[0].length);\r\n }\r\n // replace all unary operators\r\n for (let i in Object.keys(unaryOperators)) {\r\n symbol = Object.keys(unaryOperators)[i];\r\n formula = formula.replace(new RegExp(escapeRegExp(symbol), 'g'), unaryOperators[symbol] + ' ');\r\n }\r\n // filter out all other characters\r\n formula = formula.replace(/[^()A-Za-z\\\\\\s]/g, '')\r\n return formula\r\n }\r\n else return \"\"\r\n}\r\n\r\nfunction countUnary(statement) {\r\n const matchesList = (val) => (op) => op === val;\r\n let c = 0;\r\n for (c in statement.split(\"\"))\r\n if (!Object.keys(unaryOperators).some(matchesList(statement.charAt(c))))\r\n break;\r\n return c;\r\n}\r\n\r\nconst stripUnary = (s, convertStatement) => {\r\n if (convertStatement == null) \r\n convertStatement = true;\r\n let c = countUnary(s);\r\n let statement = s.substr(c)\r\n if (convertStatement) statement = convertToEG(statement)\r\n else statement = '{' + statement + '}'\r\n return \"(\".repeat(c) + statement + \")\".repeat(c)\r\n}\r\n\r\nconst convertToEG = (formula) => {\r\n if ((typeof formula === 'string' || formula instanceof String) && verifySentence(formula)) {\r\n // filter out spaces\r\n formula = formula.replace(/\\s/g, '')\r\n let binary = binaryRegex.exec(formula)\r\n let parenthesis = parenthesisRegex.exec(formula)\r\n let unary = atomicRegex.exec(formula)\r\n if (binary) {\r\n let left = convertToEG(binary[1])\r\n let right = convertToEG(binary[4])\r\n let symConversion = operators.eg[binary[3]];\r\n return symConversion.replace(/\\$1/g, left).replace(/\\$2/g, right)\r\n } else if (parenthesis) {\r\n if (countUnary(formula) != 0) {\r\n return stripUnary(formula)\r\n }\r\n return convertToEG(parenthesis[1]);\r\n } else if (unary) {\r\n return stripUnary(formula, false);\r\n } else return null;\r\n }\r\n else return null;\r\n}\r\n\r\n/* Given a string and the index of the open parenthesis, this\r\n * will return the index of the closed parenthesis\r\n */\r\nconst getMatchingParen = (formula, start) => {\r\n // hold the number of '(' minus the number of ')'\r\n let parens = 0\r\n let j = start\r\n while (j < formula.length) {\r\n if (formula[j] === '(') {\r\n parens++\r\n }\r\n else if (formula[j] === ')') {\r\n parens--\r\n // if parens is 0, then the current ')' matches the start parenthesis\r\n if (parens === 0)\r\n return j\r\n }\r\n j++\r\n }\r\n}\r\n\r\n/* Converts a string representing an Existential Graph into\r\n * a nested array. Acts recursively, calling iteslf again\r\n * When a pair of parentehses are found. If given an index i,\r\n * this will start from that index.\r\n * For example: \r\n * \"((({P})){Q}{R}){P}\" => [ [ [['P']],'Q','R' ],'P' ]\r\n */\r\nconst convertToArray = (formula, i = 0) => {\r\n if (typeof formula === 'string' || formula instanceof String) {\r\n // hold the array of the current level that will be returned\r\n let arr = []\r\n // loop through the string\r\n while (i < formula.length) {\r\n // if closing parenthesis, return the array for this subexpression\r\n if (formula[i] === '(') {\r\n // find the matching pair of parentheses of the subexpression\r\n let j = getMatchingParen(formula, i)\r\n // push the subexpression into the array\r\n let subExp = formula.substr(i+1, j-1)\r\n if (subExp)\r\n arr.push(convertToArray(formula.substr(i+1, j-1)))\r\n i = j\r\n }\r\n // if a variable is found, push it to the array\r\n else if (formula[i] === '{') {\r\n let text = formula[++i];\r\n if (text === '}') arr.push('\\u00A0')\r\n else arr.push(text)\r\n i++\r\n }\r\n i++\r\n }\r\n // return the array that values the current expression\r\n return arr\r\n }\r\n else return null\r\n}\r\n\r\nexport {\r\n convertToTeX,\r\n convertToEG,\r\n convertToArray,\r\n verifySentence\r\n}","import React from 'react';\r\n\r\nclass Toolbox extends React.Component {\r\n constructor(props) {\r\n super(props);\r\n this.state = {\r\n functions: [\r\n {\r\n str: \"Iterate/Deiterate\",\r\n func: 'iterate',\r\n highlight: { 'cut': 'all', 'var': 'all' }\r\n },\r\n {\r\n str: \"Remove Double Cut\",\r\n func: 'dcRemove',\r\n highlight: { 'cut': 'all' }\r\n },\r\n {\r\n str: \"Add Double Cut\",\r\n func: 'dcAdd',\r\n highlight: { 'cut': 'all', 'var': 'all' }\r\n },\r\n {\r\n str: \"Insertion\",\r\n func: 'insert',\r\n highlight: { 'cut': 'odd', 'var': 'odd' }\r\n },\r\n {\r\n str: \"Erasure\",\r\n func: 'erase',\r\n highlight: { 'cut': 'even', 'var': 'even' }\r\n }\r\n ]\r\n };\r\n }\r\n\r\n componentDidMount() { \r\n }\r\n\r\n render() {\r\n if (this.props.hidden) return ;\r\n return (\r\n
\r\n

Tools

\r\n {this.state.functions.map(el => (\r\n
this.props.setSelection(el.highlight, el.func)}>{el.str}
\r\n ))}\r\n
\r\n );\r\n }\r\n}\r\n\r\nexport default Toolbox;","import React from 'react';\r\nimport { ReactSVG } from 'react-svg';\r\n\r\nclass StepMenu extends React.Component {\r\n handleClick(event, step, disabled) {\r\n event.preventDefault();\r\n if (!disabled) {\r\n // Must update color before updating props to allow component to\r\n // render with the proper current color rather than the state before\r\n this.props.setStep(step);\r\n }\r\n }\r\n\r\n getColor(disabled) {\r\n return disabled ? \"rgb(136, 136, 136)\" : \"rgb(68, 68, 68)\";\r\n }\r\n\r\n render() {\r\n let { hide, currentStep, stepInfo } = this.props;\r\n if (hide) return ();\r\n let backEnabled = currentStep === (stepInfo.length - 1);\r\n let forwardEnabled = currentStep === 0;\r\n return (\r\n \r\n
\r\n
\r\n
this.handleClick(event, 0, forwardEnabled)}>\r\n \r\n
\r\n
this.handleClick(event, currentStep - 1, forwardEnabled)}>\r\n \r\n
\r\n
\r\n
\r\n
this.handleClick(event, currentStep + 1, backEnabled)}>\r\n \r\n
\r\n
this.handleClick(event, stepInfo.length - 1, backEnabled)}>\r\n \r\n
\r\n
\r\n
\r\n
\r\n Step {currentStep + 1} of {stepInfo.length}\r\n
\r\n
\r\n );\r\n }\r\n}\r\n\r\nexport default StepMenu;","export default {\r\n gridSize: 1,\r\n cutPadding: {\r\n horizontal: 10,\r\n vertical: 5\r\n },\r\n cutCornerRadius: 10,\r\n initialSeparation: 50,\r\n}","import React from 'react';\r\nimport config from './config';\r\n\r\nclass EGVariable extends React.Component {\r\n constructor(props) {\r\n super(props);\r\n this.text = React.createRef()\r\n this.getCoords = this.props.getCoords\r\n this.handleClick = this.handleClick.bind(this);\r\n this.state = {\r\n x: props.x,\r\n y: props.y,\r\n cursorOver: false,\r\n dragging: false\r\n };\r\n\r\n this.panzoom = this.props.panzoom\r\n\r\n window.addEventListener('mousemove', this.onMouseMove.bind(this))\r\n window.addEventListener('mousedown', this.handleDragStart.bind(this))\r\n window.addEventListener('mouseup', this.handleDragEnd.bind(this))\r\n window.addEventListener('click', this.handleClick)\r\n }\r\n\r\n handleClick() {\r\n if (this.state.cursorOver \r\n && this.props.enableHighlight \r\n && this.props.selectedCallback) \r\n {\r\n this.props.selectedCallback(this.props.id);\r\n this.setState({ cursorOver: false });\r\n }\r\n }\r\n\r\n componentDidMount() { \r\n this.text.current.style.cursor = \"pointer\";\r\n }\r\n\r\n handleDragStart(evt) {\r\n if (this.state.cursorOver) {\r\n this.panzoom.pause()\r\n this.setState({ dragging: true })\r\n }\r\n }\r\n\r\n handleDragEnd(evt) {\r\n this.panzoom.resume()\r\n let { x, y } = this.state;\r\n this.props.setCoords(x, y);\r\n this.setState({ dragging: false })\r\n }\r\n\r\n onMouseMove(evt) {\r\n if (this.state.dragging) {\r\n let { x, y } = this.getCoords(evt.clientX, evt.clientY)\r\n x = Math.round(x/config.gridSize)*config.gridSize\r\n y = Math.round(y/config.gridSize)*config.gridSize\r\n this.props.setCoords(x, y);\r\n this.setState({ x: x, y: y })\r\n }\r\n }\r\n\r\n componentWillUnmount() {\r\n window.removeEventListener('click', this.handleClick);\r\n window.removeEventListener('mousemove', this.onMouseMove.bind(this))\r\n window.removeEventListener('mousedown', this.handleDragStart.bind(this))\r\n window.removeEventListener('mouseup', this.handleDragEnd.bind(this))\r\n }\r\n\r\n render() {\r\n let highlight = this.state.cursorOver && this.props.enableHighlight;\r\n return (\r\n this.setState({ cursorOver: true })}\r\n onMouseLeave={() => this.setState({ cursorOver: false })}\r\n ref={this.text}>\r\n {this.props.children}\r\n \r\n );\r\n }\r\n}\r\n\r\nexport default EGVariable;","import React from 'react';\r\nimport config from './config';\r\n\r\nclass EGCut extends React.Component {\r\n constructor(props) {\r\n super(props);\r\n this.cut = React.createRef();\r\n this.BB = React.createRef();\r\n this.getBBoxData = this.getBBoxData.bind(this);\r\n this.handleClick = this.handleClick.bind(this);\r\n this.update = this.update.bind(this);\r\n this.state = { highlight: false, bounding: {_x:0,_y:0,_w:0,_h:0} };\r\n\r\n window.addEventListener('click', this.handleClick)\r\n }\r\n\r\n handleClick() {\r\n if (this.state.highlight \r\n && this.props.enableHighlight \r\n && this.props.selectedCallback) \r\n {\r\n this.props.selectedCallback(this.props.id);\r\n this.setState({ highlight: false });\r\n }\r\n }\r\n\r\n getBBoxData() {\r\n if (this.cut.current) {\r\n let { x, y, width, height } = this.cut.current.getBBox();\r\n let _x = x - config.cutPadding.horizontal;\r\n let _y = y - config.cutPadding.vertical;\r\n let _w = width + config.cutPadding.horizontal * 2;\r\n let _h = height + config.cutPadding.vertical * 2;\r\n return { _x, _y, _w, _h };\r\n }\r\n return {};\r\n }\r\n\r\n update() {\r\n if (!this.interval) {\r\n this.interval = setInterval(() => {\r\n this.setState({ bounding: this.getBBoxData() });\r\n }, 1);\r\n setTimeout(() => {\r\n clearInterval(this.interval);\r\n this.interval = null;\r\n }, 100);\r\n }\r\n }\r\n\r\n componentDidMount() { \r\n this.update()\r\n }\r\n\r\n componentDidUpdate() {\r\n this.update()\r\n }\r\n\r\n componentWillUnmount() {\r\n window.removeEventListener('click', this.handleClick);\r\n if (this.interval)\r\n clearInterval(this.interval);\r\n }\r\n\r\n render() {\r\n let childEl = this.props.children;\r\n if (childEl.length < 1) {\r\n childEl = {\" \"}\r\n }\r\n let highlight = this.state.highlight && this.props.enableHighlight;\r\n let { _x, _y, _w, _h } = this.state.bounding;\r\n return (\r\n \r\n this.setState({ highlight: true })}\r\n onMouseLeave={() => this.setState({ highlight: false })}\r\n rx={config.cutCornerRadius.toString()} \r\n ry={config.cutCornerRadius.toString()}\r\n />\r\n \r\n {this.props.children}\r\n \r\n \r\n );\r\n }\r\n}\r\n\r\nexport default EGCut;","import React from 'react';\r\nimport { convertToArray } from '../converters';\r\nimport Toolbox from './Toolbox';\r\nimport StepMenu from './StepMenu';\r\nimport EGVariable from './EGVariable';\r\nimport EGCut from './EGCut';\r\nimport './Canvas.scss';\r\nimport Panzoom from 'panzoom';\r\nimport config from './config';\r\nimport { NotificationContainer, NotificationManager } from 'react-notifications';\r\nconst nanoid = require('nanoid').nanoid;\r\n\r\n// some defaults: \r\n// blocks are automatically 22px high\r\n\r\nconst TEXT_H = 22;\r\n\r\nfunction initXY(step, level) {\r\n let data = {}\r\n let currentX = 0\r\n let currentY = 0\r\n let maxX = 0\r\n let maxY = 0\r\n\r\n // gapSize should be equal to the number of level changes\r\n // in between two variables, so that we can evenly place \r\n // them initially across the screen\r\n function initXYRecurse(step, level, gapSize) {\r\n console.log(data)\r\n for (let s in step) {\r\n if (step[s] instanceof Array && step[s].length > 0) {\r\n let id = nanoid()\r\n step[s] = { data: initXYRecurse(step[s], level + 1), id: id, type: \"cut\" }\r\n data[id] = { type: \"cut\", level: level }\r\n } else {\r\n let X = currentX;\r\n let Y = currentY;\r\n let id = nanoid()\r\n data[id] = { \r\n type: \"var\",\r\n var: step[s], \r\n x: Math.round(X/config.gridSize)*config.gridSize, \r\n y: Math.round(Y/config.gridSize)*config.gridSize,\r\n level: level\r\n }\r\n step[s] = id\r\n maxY = Y > maxY ? Y : maxY;\r\n maxX = X > maxX ? X : maxX;\r\n currentX += config.initialSeparation\r\n }\r\n }\r\n return step\r\n }\r\n return { stepZero: { data: initXYRecurse(step, level), h: maxY + TEXT_H, w: maxX }, data: data }\r\n}\r\n\r\nclass Canvas extends React.Component {\r\n constructor(props) {\r\n super(props);\r\n this.canvas = React.createRef();\r\n this.canvasContainer = React.createRef();\r\n\r\n this.renderStep = this.renderStep.bind(this);\r\n this.changePos = this.changePos.bind(this);\r\n this.getSVGCoords = this.getSVGCoords.bind(this);\r\n this.highlightCut = this.highlightCut.bind(this);\r\n this.startSelection = this.startSelection.bind(this);\r\n\r\n let { premises, conclusion, steps, data } = this.props.proof;\r\n this.state = {\r\n proof: {\r\n premises: premises,\r\n conclusion: conclusion\r\n },\r\n steps: steps || [],\r\n data: data || {},\r\n currentStep: 0,\r\n moveListeners: [],\r\n highlights: {\r\n cut: 'none', // 'none', 'odd', 'even', 'all'\r\n var: 'none'\r\n },\r\n cbFunction: null,\r\n interaction: true,\r\n functions: {\r\n insert: (id) => {\r\n console.log(\"INSERTION\")\r\n },\r\n erase: (id) => {\r\n console.log(\"ERASURE\")\r\n return this.erasure(id);\r\n },\r\n iterate: (id) => {\r\n console.log(\"ITERATION\")\r\n return this.iteration(id, this.state.steps[this.state.currentStep].data[0].id);\r\n },\r\n dcRemove: (id) => {\r\n console.log(\"DOUBLE CUT Remove\")\r\n return this.doubleCutRemove(id);\r\n },\r\n dcAdd: (id) => {\r\n console.log(\"DOUBLE CUT Add\")\r\n return this.doubleCutAdd(id);\r\n \r\n }\r\n }\r\n }\r\n }\r\n\r\n startSelection(selectable, nameOfFunction) {\r\n let { steps, currentStep } = this.state;\r\n // only allow steps to be conducted at the end of a proof\r\n if (currentStep+1 !== steps.length) {\r\n return\r\n }\r\n this.setState({ \r\n highlights: selectable, \r\n interaction: false, \r\n cbFunction: (id) => {\r\n let successful = this.state.functions[nameOfFunction](id); \r\n if (successful) \r\n this.setState({ \r\n highlights: {\r\n cut: 'none', \r\n var: 'none'\r\n },\r\n interaction: true, \r\n cbFunction: null });\r\n }\r\n });\r\n }\r\n\r\n /* Given a copyID and insertID, the iteration function creates a new step,\r\n * and adds a copy of the data represented by copyID at the location of insertID\r\n * only if the location of insertID is a child of copyID\r\n */\r\n iteration(copyID, insertID) {\r\n let { steps, currentStep, data } = this.state;\r\n let step = this.copyStep(steps[currentStep]);\r\n // If the insertID data is not in a subgraph of the copID data, return\r\n if (!this.isInNestedGraph(step, insertID, copyID)) {\r\n console.log(\"Insert selection is not in a subgraph of Copy selection\");\r\n return false;\r\n }\r\n // use findID to find the data represented by the two IDs\r\n let copy = this.copyContents(this.findID(step, copyID));\r\n if (!copy) {\r\n console.log(\"Copy ID could not be found in Iterate\");\r\n return false;\r\n }\r\n let insert = this.findID(step, insertID);\r\n if (!insert) {\r\n console.log(\"Insert ID could not be found in Iterate\");\r\n return false;\r\n }\r\n insert.data = insert.data.concat(copy);\r\n // Change the levels of the copy data\r\n this.changeCutLevel(step, copy.id, data[insert.id].level + 1)\r\n // Update the state\r\n currentStep+=1;\r\n steps.push(step);\r\n this.setState({ steps: steps, currentStep: currentStep, data:data });\r\n return true;\r\n }\r\n\r\n erasure(id) {\r\n let { steps, currentStep, data } = this.state;\r\n // Create a new step\r\n let step = this.copyStep(steps[currentStep]);\r\n // Find the data that will be erased\r\n let erased = this.findID(step, id);\r\n if (!erased) {\r\n return false;\r\n }\r\n // Get the parent of the erased section\r\n let parent = this.findParent(step, id)\r\n if (!parent) {\r\n return false;\r\n }\r\n // Remove the erased data from the parent's data array\r\n const index = parent.data.indexOf(erased);\r\n if (index > -1)\r\n parent.data.splice(index, 1);\r\n else {\r\n return false;\r\n }\r\n // Update the state\r\n currentStep+=1;\r\n steps.push(step);\r\n this.setState({ steps: steps, currentStep: currentStep, data:data });\r\n return true;\r\n }\r\n\r\n /* Adds a double cut given the ID of the data that will be inside the cut.\r\n * Will only run if the current step is the last step.\r\n */\r\n doubleCutAdd(ID) {\r\n let { steps, currentStep, data } = this.state;\r\n // create a new step\r\n let step = this.copyStep(steps[currentStep]);\r\n // use findID to find the data represented by the id\r\n // this is the data that will be inside the two new cuts\r\n let inside = this.findID(step, ID);\r\n if (!inside) {\r\n return false;\r\n }\r\n // create a new cut with another one inside it\r\n let cut1_id = nanoid();\r\n let cut2_id = nanoid();\r\n let cut2 = {\r\n data: [inside],\r\n id: cut2_id,\r\n type: \"cut\"\r\n }\r\n let cut1 = {\r\n data: [cut2],\r\n id: cut1_id,\r\n type: \"cut\"\r\n }\r\n // Set the levels of the two cuts\r\n let level = data[ID].level\r\n data[cut2_id] = { type: \"cut\", level: level + 1};\r\n data[cut1_id] = { type: \"cut\", level: level};\r\n // increase the level of the inside cut along with all cuts inside of it by 2\r\n this.changeCutLevel(step, ID, 2)\r\n\r\n // get the parent of the selection\r\n let parent = this.findParent(step, ID)\r\n if (!parent) {\r\n return false;\r\n }\r\n // Add the contents of the new cuts to the data array\r\n // after removing the original contents\r\n const index = parent.data.indexOf(inside);\r\n if (index > -1) {\r\n parent.data.splice(index, 1);\r\n }\r\n parent.data = parent.data.concat(cut1);\r\n // Change the state data accordingly\r\n currentStep+=1;\r\n steps.push(step);\r\n this.setState({ steps: steps, currentStep: currentStep, data:data });\r\n return true;\r\n }\r\n\r\n /* Removes a double cut given the ID of the outside cut.\r\n * Will only run if the current step is the last step.\r\n * Creates a deep copy of the current step, and replaces the cut with\r\n * the given ID with the contents of the second cut, only if they exist.\r\n * Then adds the edited copy of the current step to the end of the step array.\r\n */\r\n doubleCutRemove(cutID) {\r\n let { steps, currentStep, data } = this.state;\r\n // Create a new step\r\n let step = this.copyStep(steps[currentStep]);\r\n\r\n // use findID to find the cut with the given ID\r\n let firstCut = this.findID(step, cutID);\r\n // If it is actually a cut and has another cut inside\r\n if (firstCut && firstCut.type === \"cut\") {\r\n let secondCut = firstCut.data;\r\n if (secondCut && secondCut.length === 1 && secondCut[0].type === \"cut\") {\r\n // Get the data inside the second cut\r\n let newContents = secondCut[0].data;\r\n // Get the parent of the original cut being removed\r\n let parent = this.findParent(step, cutID)\r\n if (!parent) {\r\n return false;\r\n }\r\n this.changeCutLevel(step, secondCut[0].id, -2)\r\n // Remove the first cut from the data array\r\n const index = parent.data.indexOf(firstCut);\r\n if (index > -1) {\r\n parent.data.splice(index, 1);\r\n }\r\n // Add the contents of the second cut to the data array\r\n parent.data = parent.data.concat(newContents);\r\n // Update the state\r\n currentStep+=1;\r\n steps.push(step);\r\n this.setState({ steps: steps, currentStep: currentStep, data:data });\r\n return true;\r\n }\r\n else return false;\r\n }\r\n else return false;\r\n }\r\n\r\n\r\n /* Given a step and two IDs, will return true if the data of ChildID is\r\n * in a nested graph of parentID in the current step.\r\n */\r\n isInNestedGraph(step, childID, parentID) {\r\n let parentStep = this.findParent(step, parentID);\r\n if (!parentStep) {\r\n console.log(\"Parent Data could not be found\");\r\n return false;\r\n }\r\n let childStep = this.findID(parentStep, childID);\r\n if (!childStep) {\r\n console.log(\"Child is not in nested graph of Parent\");\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /* Given a step or a cut, will copy the contents inside with new IDs\r\n * and return the new data. This permits inserting new data into the graph.\r\n * Levels for cuts will start at 0 and increase accordingly\r\n */\r\n copyContents(step) {\r\n let { data } = this.state;\r\n // Copies the data of a map and returns it\r\n // Also updates the state.data map according to new generated IDs\r\n function copyDataMap(map, level) {\r\n let newMap = {};\r\n for (let m in map) {\r\n // If an ID is found, generate a new one\r\n if (m === 'id') {\r\n let id = nanoid();\r\n newMap[m] = id;\r\n // Add the new data to state.data via a deep copy\r\n data[id] = {\r\n type: \"cut\",\r\n level: level\r\n }\r\n }\r\n // Otherwise, if not a data array, copy the contents\r\n else if (m !== 'data'){\r\n newMap[m] = map[m]\r\n }\r\n // If a data array, copy using helper function\r\n else {\r\n newMap[m] = copyDataArray(map[m], level+1)\r\n }\r\n }\r\n return newMap;\r\n }\r\n // Copies the data of an array and returns it\r\n // Also updates state.data according to new generated IDs\r\n function copyDataArray(arr, level) {\r\n let newArr = [];\r\n for (let a in arr) {\r\n // If an ID found, generate a new one\r\n if (typeof arr[a] === 'string') {\r\n let id = nanoid();\r\n newArr.push(id);\r\n // Add the new data to state.data via a deep copy\r\n data[id] = {\r\n type: \"var\",\r\n var: data[arr[a]].var,\r\n x: data[arr[a]].x,\r\n y: data[arr[a]].y,\r\n }\r\n }\r\n // otherwise, call the other helper function to copy contents\r\n else {\r\n newArr.push(copyDataMap(arr[a], level))\r\n }\r\n }\r\n return newArr;\r\n }\r\n let newStep = copyDataMap(step, 0);\r\n this.setState({ data: data })\r\n return newStep;\r\n }\r\n\r\n /* Given a step and the ID of a cut, will iterate through all cuts within\r\n * that cut and change their level by a specified amount.\r\n */\r\n changeCutLevel(step, id, change) {\r\n let { data } = this.state\r\n // If the ID is for a variable, only increase it's level\r\n if (data[id].type === \"var\") {\r\n data[id].level += change;\r\n return\r\n }\r\n // when true, the levels should change in the functions below\r\n let idFound = false\r\n // Changes the \r\n function changeLevelMap(map) {\r\n // get the id for the current map\r\n let mapID;\r\n if (map.id) {\r\n mapID = map.id\r\n // if it matches the id being searched, update the boolean\r\n if (mapID === id) {\r\n idFound = true;\r\n }\r\n }\r\n // If the ID has been found, update the level of the current cut\r\n if (idFound) {\r\n data[mapID].level += change;\r\n }\r\n // call the function of the data array if it exists\r\n if (map.data){\r\n changeLevelArray(map.data);\r\n }\r\n }\r\n function changeLevelArray(arr) {\r\n for (let a in arr) {\r\n // If a non-string is found (a cut)\r\n if (typeof arr[a] !== 'string') {\r\n // Change the level of the cut\r\n changeLevelMap(arr[a])\r\n }\r\n // If string is found, change the level of the variable\r\n else if (idFound){\r\n data[arr[a]].level += change;\r\n }\r\n }\r\n }\r\n changeLevelArray(step.data)\r\n this.setState({ data: data })\r\n }\r\n\r\n // Performs a deep copy of oldStep into newStep, used to not change previous steps\r\n // By allowing them to be copied without using a reference\r\n copyStep(oldStep) {\r\n let newStep = {};\r\n function copyDataMap(oldData) {\r\n let newData = {};\r\n for (let d in oldData) {\r\n // If an id or type if found, copy directly\r\n if(typeof oldData[d] === 'string') {\r\n newData[d] = oldData[d];\r\n }\r\n // Otherwise if an array is found, copy using helper function\r\n else {\r\n newData[d] = copyDataArray(oldData[d]);\r\n }\r\n }\r\n return newData;\r\n }\r\n function copyDataArray(oldData) {\r\n let newData = [];\r\n for (let d in oldData) {\r\n // If an ID is found (variable), copy directly\r\n if(typeof oldData[d] === 'string') {\r\n newData.push(oldData[d]);\r\n }\r\n // If a map was found (cut), copy using helper function\r\n else {\r\n newData.push(copyDataMap(oldData[d]));\r\n }\r\n }\r\n return newData;\r\n }\r\n // Copy the data, width, and height of the original into the new step\r\n newStep.data = copyDataArray(oldStep.data);\r\n newStep.h = oldStep.h;\r\n newStep.w = oldStep.w;\r\n return newStep;\r\n }\r\n\r\n /* Finds and returns the item that is the parent of the item\r\n * with the specified ID, given the step to search as well.\r\n */\r\n findParent(searchedStep, id) {\r\n // holds the parent of the id\r\n let parent = searchedStep\r\n // Searches an array for the ID, returns true if it is found\r\n function findInArray(arr) {\r\n for (let a in arr) {\r\n // If an ID is found, compare it\r\n if (typeof arr[a] === 'string') {\r\n if (arr[a] === id) {\r\n return true;\r\n }\r\n }\r\n // Otherwise if a datamap is found, check the ID\r\n else {\r\n // If ID matches, return true\r\n if (arr[a].id && arr[a].id === id) {\r\n return true;\r\n }\r\n // Otherwise, search the datamap\r\n else {\r\n findInMap(arr[a])\r\n }\r\n }\r\n }\r\n return false;\r\n }\r\n function findInMap(map) {\r\n // if the map contains data, search the data\r\n if (map.data) {\r\n // if found, set parent to this map\r\n if(findInArray(map.data)) {\r\n parent = map;\r\n }\r\n }\r\n }\r\n findInArray(searchedStep.data);\r\n return parent;\r\n }\r\n\r\n // finds and returns the item with the specified ID in a given step\r\n findID(searchedStep, id) {\r\n // Find the ID in an array\r\n function findIDArray(arr) {\r\n for (let a in arr) {\r\n // if a string, aka an ID\r\n if (typeof arr[a] === 'string') {\r\n // return the ID if found\r\n if (arr[a] === id) {\r\n return id;\r\n }\r\n }\r\n // if a data map is found with the correct id, return the data map\r\n else if (arr[a].id === id) {\r\n return arr[a];\r\n // otherwise, call findID step on the datamap that has the incorrect ID\r\n } else {\r\n let s = findIDMap(arr[a]);\r\n if (s)\r\n return s;\r\n }\r\n }\r\n }\r\n // Finds the ID in a data map representing a step\r\n function findIDMap(step) {\r\n for (let s in step) {\r\n // if an array is found, call findIDArray on each element\r\n if (step[s] instanceof Array) {\r\n return findIDArray(step[s]);\r\n // if an id is found, check if it matches and return the data if so\r\n } else if (s === \"id\") {\r\n if (step[s] === id)\r\n return step;\r\n }\r\n }\r\n }\r\n return findIDMap(searchedStep);\r\n }\r\n\r\n changePos(id, x, y) {\r\n let { data } = this.state;\r\n Object.assign(data[id], { x: x, y: y })\r\n this.setState(data)\r\n }\r\n\r\n highlightCut(level) {\r\n if (this.state.highlights.cut === 'all') return true;\r\n let odd = false;\r\n if (level % 2 === 1) odd = true;\r\n if (this.state.highlights.cut === 'odd' && odd) return true;\r\n else if (this.state.highlights.cut === 'even' && !odd) return true;\r\n return false;\r\n }\r\n\r\n highlightVar(level) {\r\n if (this.state.highlights.var === 'all') return true;\r\n let odd = false;\r\n if (level % 2 === 1) odd = true;\r\n if (this.state.highlights.var === 'odd' && odd) return true;\r\n else if (this.state.highlights.var === 'even' && !odd) return true;\r\n return false;\r\n }\r\n\r\n renderStep(stepIndex) {\r\n let { data } = this.state;\r\n let step = this.state.steps[stepIndex]\r\n if (step) {\r\n const setXY = (id,x,y) => {\r\n data[id].x = x;\r\n data[id].y = y;\r\n this.setState({ data: data })\r\n }\r\n\r\n const renderRecurse = (step) => {\r\n let jsx = [];\r\n for (let s in step) {\r\n if (step[s].type === \"cut\") {\r\n let level = data[step[s].id].level;\r\n let groupElement = (\r\n \r\n {renderRecurse(step[s].data)}\r\n \r\n );\r\n jsx.push(groupElement);\r\n } else {\r\n let el = this.state.data[step[s]];\r\n let level = data[step[s]].level;\r\n jsx.unshift(\r\n setXY(step[s],x,y)}\r\n key={step[s]}>\r\n {el.var}\r\n \r\n );\r\n }\r\n }\r\n return jsx;\r\n }\r\n renderRecurse.bind(this);\r\n return renderRecurse(step.data)\r\n }\r\n }\r\n\r\n componentDidMount() { \r\n this.panzoom = Panzoom(this.canvas.current, {\r\n maxZoom: 6,\r\n minZoom: 0.5\r\n });\r\n // this.canvasContainer.current.addEventListener('wheel', this.panzoom.zoomWithWheel);\r\n const vw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);\r\n const vh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);\r\n // if there are no existing steps, init first step\r\n let { steps } = this.state;\r\n if (steps.length === 0) {\r\n let { premises, conclusion } = this.state.proof;\r\n let { stepZero, data } = initXY(convertToArray(premises.join('')), 0);\r\n steps.push(stepZero);\r\n this.setState({ steps: steps, data: data });\r\n }\r\n // required to use setState to trigger re-render after creation of panzoom\r\n this.setState({ currentStep: 0 });\r\n let step = this.state.steps[this.state.currentStep];\r\n\r\n this.panzoom.moveTo(vw/2 - step.w, vh/2 - step.h);\r\n this.panzoom.zoomTo(vw/2 - step.w, vh/2 - step.h, 2);\r\n }\r\n\r\n componentWillUnmount() {\r\n window.removeEventListener('resize', this);\r\n }\r\n\r\n getSVGCoords(domX, domY) {\r\n var pt = this.canvasContainer.current.createSVGPoint();\r\n\r\n pt.x = domX;\r\n pt.y = domY;\r\n\r\n return pt.matrixTransform(this.canvas.current.getScreenCTM().inverse());\r\n }\r\n\r\n render() {\r\n let zoomWithWheel = () => {}\r\n let { steps, currentStep } = this.state;\r\n if (this.panzoom)\r\n zoomWithWheel = this.panzoom.zoomWithWheel\r\n return (\r\n
\r\n
\r\n );\r\n }\r\n}\r\n\r\nexport default Canvas;\r\n","import React from 'react';\r\nimport verify from '../verifySentence';\r\nimport { convertToTeX, convertToEG } from '../converters';\r\n// KATEX\r\nimport 'katex/dist/katex.min.css';\r\nimport TeX from '@matejmazur/react-katex';\r\nimport './CreateNew.scss';\r\n\r\nclass CreateNew extends React.Component {\r\n constructor(props) {\r\n super(props);\r\n \r\n this.state = {\r\n premises: [\r\n ''\r\n ],\r\n conclusion: ''\r\n };\r\n\r\n this.handleChange.bind(this)\r\n this.removePremise.bind(this)\r\n this.verify = this.verify.bind(this)\r\n this.create = this.create.bind(this)\r\n }\r\n\r\n componentDidMount() {\r\n\r\n }\r\n\r\n handleChange(e, i) {\r\n if (i != null) {\r\n let { premises } = this.state;\r\n premises[i] = e.target.value;\r\n this.setState({ premises: premises })\r\n }\r\n else this.setState({ conclusion: e.target.value })\r\n }\r\n\r\n removePremise(index) {\r\n let { premises } = this.state;\r\n premises.splice(index, 1);\r\n this.setState({ premises: premises })\r\n }\r\n\r\n verify() {\r\n let { premises, conclusion } = this.state;\r\n for (let i in premises) {\r\n if (premises[i] === '' || !premises[i])\r\n return false;\r\n }\r\n if (conclusion === '' || !conclusion)\r\n return false;\r\n return true;\r\n }\r\n\r\n create() {\r\n console.log(\"Creating...\")\r\n console.log(\"Verification concluded \" + this.verify())\r\n if (this.verify()) {\r\n let { premises, conclusion } = this.state;\r\n for (let i in premises) {\r\n premises[i] = convertToEG(premises[i])\r\n console.log(premises[i])\r\n }\r\n conclusion = convertToEG(conclusion)\r\n this.props.setupFunc(premises, conclusion, [])\r\n }\r\n }\r\n\r\n getFormulaCell(formula, i) {\r\n let tex, eg\r\n if (verify(formula)) {\r\n tex = convertToTeX(formula);\r\n eg = convertToEG(formula);\r\n }\r\n let closeBtn = this.removePremise(i)}>\r\n ✕\r\n ;\r\n let formulaInput = this.handleChange(e,i) } />;\r\n if (i == null) {\r\n formulaInput = this.handleChange(e) } />;\r\n closeBtn = ;\r\n }\r\n if (i === 0) \r\n closeBtn = ;\r\n return (\r\n \r\n \r\n {formulaInput}\r\n \r\n \r\n {tex && }\r\n \r\n \r\n {eg && }\r\n \r\n { closeBtn }\r\n \r\n );\r\n }\r\n\r\n render() {\r\n let { premises, conclusion } = this.state;\r\n return (\r\n
\r\n

Create New

\r\n

File Name

\r\n \r\n \r\n \r\n
\r\n

Premises

\r\n \r\n \r\n \r\n \r\n {premises.map((formula,i) => this.getFormulaCell(formula, i))}\r\n \r\n \r\n \r\n
\r\n Formula\r\n TeX notationEG notation\r\n
this.setState({ premises: premises.concat(['']) }) }>\r\n Add New Premise\r\n \r\n
\r\n

Conclusion

\r\n \r\n {this.getFormulaCell(conclusion)}\r\n
\r\n
\r\n );\r\n }\r\n}\r\n\r\nexport default CreateNew;","import React from 'react';\r\nimport CreateNew from './CreateNew';\r\nimport { ReactSVG } from 'react-svg';\r\nimport './intro.scss';\r\n\r\nconst IntroContent = () => (\r\n
\r\n
\r\n

Existential Graphs

\r\n

\r\n Using this tool, you can initialize proofs in the existential graph schema and then you can go through the process of solving them. You can save these proofs and look back at them later.\r\n

\r\n
\r\n
\r\n
\r\n

Recent Proofs

\r\n
\r\n
\r\n);\r\n\r\nclass IntroWindow extends React.Component {\r\n constructor(props) {\r\n super(props);\r\n this.createView = React.createRef();\r\n this.callCreate = this.callCreate.bind(this);\r\n this.animateAway = this.animateAway.bind(this);\r\n this.state = {\r\n createShown: false,\r\n floatingWindowCSS: 'floating-window shown'\r\n };\r\n }\r\n\r\n componentDidMount() {\r\n }\r\n\r\n animateAway() {\r\n this.setState({ floatingWindowCSS: 'floating-window' })\r\n }\r\n\r\n callCreate() {\r\n this.createView.current.create();\r\n }\r\n\r\n render() {\r\n const { createShown, floatingWindowCSS } = this.state;\r\n return (\r\n
\r\n {!createShown && }\r\n {createShown && }\r\n {!createShown && (\r\n
\r\n \r\n \r\n
\r\n )}\r\n {createShown && (\r\n
\r\n \r\n \r\n
\r\n )}\r\n
\r\n );\r\n }\r\n}\r\n\r\nexport default IntroWindow;","import React from 'react';\r\nimport './App.scss';\r\nimport Canvas from './canvas/Canvas';\r\nimport IntroWindow from './intro/IntroWindow';\r\n\r\nclass App extends React.Component {\r\n constructor(props) {\r\n super(props);\r\n \r\n this.createNewProof = this.createNewProof.bind(this);\r\n this.setupProof = this.setupProof.bind(this);\r\n this.openCanvas = this.openCanvas.bind(this);\r\n this.saveProof = this.saveProof.bind(this);\r\n this.introWindow = React.createRef();\r\n this.state = {\r\n initialCSS: 'initial',\r\n canvasOpen: false,\r\n popupOpen: false,\r\n proof: {\r\n premises: [],\r\n conclusion: '',\r\n steps: []\r\n }\r\n };\r\n // this.state = {\r\n // initialCSS: 'initial',\r\n // canvasOpen: true,\r\n // popupOpen: false,\r\n // proof: {premises: [\"({Q})(({P}){Q})\"], conclusion: \"{Q}\", steps:[] }\r\n // };\r\n }\r\n\r\n saveProof(proof) {\r\n this.setState({ proof: proof });\r\n }\r\n\r\n setupProof(premises, conclusion, steps) {\r\n this.setState({ \r\n proof: { \r\n premises: premises,\r\n conclusion: conclusion,\r\n steps: steps\r\n },\r\n initialCSS: 'initial whiteBG'\r\n });\r\n this.introWindow.current.animateAway();\r\n setTimeout(this.openCanvas, 1000);\r\n }\r\n\r\n openCanvas() {\r\n this.setState({ \r\n canvasOpen: true\r\n });\r\n }\r\n\r\n createNewProof() {\r\n this.setState({ popupOpen: true })\r\n }\r\n\r\n render() {\r\n if (this.state.canvasOpen) {\r\n return (\r\n
\r\n \r\n
\r\n );\r\n }\r\n return (\r\n
\r\n \r\n
\r\n );\r\n }\r\n}\r\n\r\nexport default App;\r\n","// This optional code is used to register a service worker.\r\n// register() is not called by default.\r\n\r\n// This lets the app load faster on subsequent visits in production, and gives\r\n// it offline capabilities. However, it also means that developers (and users)\r\n// will only see deployed updates on subsequent visits to a page, after all the\r\n// existing tabs open on the page have been closed, since previously cached\r\n// resources are updated in the background.\r\n\r\n// To learn more about the benefits of this model and instructions on how to\r\n// opt-in, read https://bit.ly/CRA-PWA\r\n\r\nconst isLocalhost = Boolean(\r\n window.location.hostname === 'localhost' ||\r\n // [::1] is the IPv6 localhost address.\r\n window.location.hostname === '[::1]' ||\r\n // 127.0.0.0/8 are considered localhost for IPv4.\r\n window.location.hostname.match(\r\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\r\n )\r\n);\r\n\r\nexport function register(config) {\r\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\r\n // The URL constructor is available in all browsers that support SW.\r\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\r\n if (publicUrl.origin !== window.location.origin) {\r\n // Our service worker won't work if PUBLIC_URL is on a different origin\r\n // from what our page is served on. This might happen if a CDN is used to\r\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\r\n return;\r\n }\r\n\r\n window.addEventListener('load', () => {\r\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\r\n\r\n if (isLocalhost) {\r\n // This is running on localhost. Let's check if a service worker still exists or not.\r\n checkValidServiceWorker(swUrl, config);\r\n\r\n // Add some additional logging to localhost, pointing developers to the\r\n // service worker/PWA documentation.\r\n navigator.serviceWorker.ready.then(() => {\r\n console.log(\r\n 'This web app is being served cache-first by a service ' +\r\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\r\n );\r\n });\r\n } else {\r\n // Is not localhost. Just register service worker\r\n registerValidSW(swUrl, config);\r\n }\r\n });\r\n }\r\n}\r\n\r\nfunction registerValidSW(swUrl, config) {\r\n navigator.serviceWorker\r\n .register(swUrl)\r\n .then(registration => {\r\n registration.onupdatefound = () => {\r\n const installingWorker = registration.installing;\r\n if (installingWorker == null) {\r\n return;\r\n }\r\n installingWorker.onstatechange = () => {\r\n if (installingWorker.state === 'installed') {\r\n if (navigator.serviceWorker.controller) {\r\n // At this point, the updated precached content has been fetched,\r\n // but the previous service worker will still serve the older\r\n // content until all client tabs are closed.\r\n console.log(\r\n 'New content is available and will be used when all ' +\r\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\r\n );\r\n\r\n // Execute callback\r\n if (config && config.onUpdate) {\r\n config.onUpdate(registration);\r\n }\r\n } else {\r\n // At this point, everything has been precached.\r\n // It's the perfect time to display a\r\n // \"Content is cached for offline use.\" message.\r\n console.log('Content is cached for offline use.');\r\n\r\n // Execute callback\r\n if (config && config.onSuccess) {\r\n config.onSuccess(registration);\r\n }\r\n }\r\n }\r\n };\r\n };\r\n })\r\n .catch(error => {\r\n console.error('Error during service worker registration:', error);\r\n });\r\n}\r\n\r\nfunction checkValidServiceWorker(swUrl, config) {\r\n // Check if the service worker can be found. If it can't reload the page.\r\n fetch(swUrl, {\r\n headers: { 'Service-Worker': 'script' }\r\n })\r\n .then(response => {\r\n // Ensure service worker exists, and that we really are getting a JS file.\r\n const contentType = response.headers.get('content-type');\r\n if (\r\n response.status === 404 ||\r\n (contentType != null && contentType.indexOf('javascript') === -1)\r\n ) {\r\n // No service worker found. Probably a different app. Reload the page.\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister().then(() => {\r\n window.location.reload();\r\n });\r\n });\r\n } else {\r\n // Service worker found. Proceed as normal.\r\n registerValidSW(swUrl, config);\r\n }\r\n })\r\n .catch(() => {\r\n console.log(\r\n 'No internet connection found. App is running in offline mode.'\r\n );\r\n });\r\n}\r\n\r\nexport function unregister() {\r\n if ('serviceWorker' in navigator) {\r\n navigator.serviceWorker.ready\r\n .then(registration => {\r\n registration.unregister();\r\n })\r\n .catch(error => {\r\n console.error(error.message);\r\n });\r\n }\r\n}\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport './index.scss';\r\nimport App from './App';\r\nimport * as serviceWorker from './serviceWorker';\r\n\r\nReactDOM.render(, document.getElementById('root'));\r\n\r\n// If you want your app to work offline and load faster, you can change\r\n// unregister() to register() below. Note this comes with some pitfalls.\r\n// Learn more about service workers: https://bit.ly/CRA-PWA\r\nserviceWorker.unregister();\r\n"],"sourceRoot":""} \ No newline at end of file -- 2.51.2