diff --git a/dev/build/esbuild.js b/dev/build/esbuild.js
index 46357038a..57a224876 100644
--- a/dev/build/esbuild.js
+++ b/dev/build/esbuild.js
@@ -1,7 +1,6 @@
 #!/usr/bin/env node
 
 const esbuild = require('esbuild');
-const fs = require('fs');
 const path = require('path');
 
 // Check if we're building for production
@@ -9,20 +8,19 @@ const path = require('path');
 const isProd = process.argv[2] === 'production';
 
 // Gather our input files
-const jsInDir = path.join(__dirname, '../../resources/js');
-const jsInDirFiles = fs.readdirSync(jsInDir, 'utf8');
-const entryFiles = jsInDirFiles
-    .filter(f => f.endsWith('.js') || f.endsWith('.mjs'))
-    .map(f => path.join(jsInDir, f));
+const entryPoints = {
+    app: path.join(__dirname, '../../resources/js/app.js'),
+    code: path.join(__dirname, '../../resources/js/code/index.mjs'),
+};
 
 // Locate our output directory
-const outDir = path.join(__dirname, '../../public/dist');
+const outdir = path.join(__dirname, '../../public/dist');
 
 // Build via esbuild
 esbuild.build({
     bundle: true,
-    entryPoints: entryFiles,
-    outdir: outDir,
+    entryPoints,
+    outdir,
     sourcemap: true,
     target: 'es2020',
     mainFields: ['module', 'main'],
diff --git a/package-lock.json b/package-lock.json
index 1448d592f..c141e654a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,21 +5,131 @@
   "packages": {
     "": {
       "dependencies": {
+        "@codemirror/commands": "^6.0.1",
+        "@codemirror/language": "^6.2.1",
+        "@codemirror/legacy-modes": "^6.1.0",
+        "@codemirror/state": "^6.1.0",
+        "@codemirror/view": "^6.1.2",
         "clipboard": "^2.0.11",
-        "codemirror": "^5.65.5",
+        "codemirror": "^6.0.1",
         "dropzone": "^5.9.3",
         "markdown-it": "^13.0.1",
         "markdown-it-task-lists": "^2.1.1",
-        "snabbdom": "^3.5.0",
+        "snabbdom": "^3.5.1",
         "sortablejs": "^1.15.0"
       },
       "devDependencies": {
         "chokidar-cli": "^3.0",
-        "esbuild": "0.14.42",
+        "esbuild": "0.14.51",
         "livereload": "^0.9.3",
         "npm-run-all": "^4.1.5",
         "punycode": "^2.1.1",
-        "sass": "^1.52.1"
+        "sass": "^1.54.0"
+      }
+    },
+    "node_modules/@codemirror/autocomplete": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.1.0.tgz",
+      "integrity": "sha512-wtO4O5WDyXhhCd4q4utDIDZxnQfmJ++3dGBCG9LMtI79+92OcA1DVk/n7BEupKmjIr8AzvptDz7YQ9ud6OkU+A==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0"
+      },
+      "peerDependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/commands": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.0.1.tgz",
+      "integrity": "sha512-iNHDByicYqQjs0Wo1MKGfqNbMYMyhS9WV6EwMVwsHXImlFemgEUC+c5X22bXKBStN3qnwg4fArNZM+gkv22baQ==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "node_modules/@codemirror/language": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz",
+      "integrity": "sha512-MC3svxuvIj0MRpFlGHxLS6vPyIdbTr2KKPEW46kCoCXw2ktb4NTkpkPBI/lSP/FoNXLCBJ0mrnUi1OoZxtpW1Q==",
+      "dependencies": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0",
+        "style-mod": "^4.0.0"
+      }
+    },
+    "node_modules/@codemirror/legacy-modes": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.1.0.tgz",
+      "integrity": "sha512-V/PgGpndkZeTn3Hdlg/gd8MLFdyvTCIX+iwJzjUw5iNziWiNsAY8X0jvf7m3gSfxnKkNzmid6l0g4rYSpiDaCw==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0"
+      }
+    },
+    "node_modules/@codemirror/lint": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.0.0.tgz",
+      "integrity": "sha512-nUUXcJW1Xp54kNs+a1ToPLK8MadO0rMTnJB8Zk4Z8gBdrN0kqV7uvUraU/T2yqg+grDNR38Vmy/MrhQN/RgwiA==",
+      "dependencies": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "crelt": "^1.0.5"
+      }
+    },
+    "node_modules/@codemirror/search": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.0.1.tgz",
+      "integrity": "sha512-uOinkOrM+daMduCgMPomDfKLr7drGHB4jHl3Vq6xY2WRlL7MkNsBE0b+XHYa/Mee2npsJOgwvkW4n1lMFeBW2Q==",
+      "dependencies": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "crelt": "^1.0.5"
+      }
+    },
+    "node_modules/@codemirror/state": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.1.0.tgz",
+      "integrity": "sha512-qbUr94DZTe6/V1VS7LDLz11rM/1t/nJxR1El4I6UaxDEdc0aZZvq6JCLJWiRmUf95NRAnDH6fhXn+PWp9wGCIg=="
+    },
+    "node_modules/@codemirror/view": {
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.1.2.tgz",
+      "integrity": "sha512-puUydfKwfmOo+ixtuB+uN/ZpcteEYSnpjHmMaow1sOQhNICsKtGBup3i9ybVqyzDagARRYzSHTWjbdeHqmn31w==",
+      "dependencies": {
+        "@codemirror/state": "^6.0.0",
+        "style-mod": "^4.0.0",
+        "w3c-keyname": "^2.2.4"
+      }
+    },
+    "node_modules/@lezer/common": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.0.tgz",
+      "integrity": "sha512-ohydQe+Hb+w4oMDvXzs8uuJd2NoA3D8YDcLiuDsLqH+yflDTPEpgCsWI3/6rH5C3BAedtH1/R51dxENldQceEA=="
+    },
+    "node_modules/@lezer/highlight": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.0.0.tgz",
+      "integrity": "sha512-nsCnNtim90UKsB5YxoX65v3GEIw3iCHw9RM2DtdgkiqAbKh9pCdvi8AWNwkYf10Lu6fxNhXPpkpHbW6mihhvJA==",
+      "dependencies": {
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "node_modules/@lezer/lr": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.2.0.tgz",
+      "integrity": "sha512-TgEpfm9br2SX8JwtwKT8HsQZKuFkLRg6g+IRxObk9nVKQLKnkP3oMh+QGcTBL9GQsfQ2ADtKPbj2iGSMf3ytiA==",
+      "dependencies": {
+        "@lezer/common": "^1.0.0"
       }
     },
     "node_modules/ansi-regex": {
@@ -195,9 +305,18 @@
       }
     },
     "node_modules/codemirror": {
-      "version": "5.65.5",
-      "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.5.tgz",
-      "integrity": "sha512-HNyhvGLnYz5c+kIsB9QKVitiZUevha3ovbIYaQiGzKo7ECSL/elWD9RXt3JgNr0NdnyqE9/Rc/7uLfkJQL638w=="
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
+      "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
+      "dependencies": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/commands": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/lint": "^6.0.0",
+        "@codemirror/search": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0"
+      }
     },
     "node_modules/color-convert": {
       "version": "1.9.3",
@@ -220,6 +339,11 @@
       "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
       "dev": true
     },
+    "node_modules/crelt": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.5.tgz",
+      "integrity": "sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA=="
+    },
     "node_modules/cross-spawn": {
       "version": "6.0.5",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -345,9 +469,9 @@
       }
     },
     "node_modules/esbuild": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.42.tgz",
-      "integrity": "sha512-V0uPZotCEHokJdNqyozH6qsaQXqmZEOiZWrXnds/zaH/0SyrIayRXWRB98CENO73MIZ9T3HBIOsmds5twWtmgw==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.51.tgz",
+      "integrity": "sha512-+CvnDitD7Q5sT7F+FM65sWkF8wJRf+j9fPcprxYV4j+ohmzVj2W7caUqH2s5kCaCJAfcAICjSlKhDCcvDpU7nw==",
       "dev": true,
       "hasInstallScript": true,
       "bin": {
@@ -357,32 +481,32 @@
         "node": ">=12"
       },
       "optionalDependencies": {
-        "esbuild-android-64": "0.14.42",
-        "esbuild-android-arm64": "0.14.42",
-        "esbuild-darwin-64": "0.14.42",
-        "esbuild-darwin-arm64": "0.14.42",
-        "esbuild-freebsd-64": "0.14.42",
-        "esbuild-freebsd-arm64": "0.14.42",
-        "esbuild-linux-32": "0.14.42",
-        "esbuild-linux-64": "0.14.42",
-        "esbuild-linux-arm": "0.14.42",
-        "esbuild-linux-arm64": "0.14.42",
-        "esbuild-linux-mips64le": "0.14.42",
-        "esbuild-linux-ppc64le": "0.14.42",
-        "esbuild-linux-riscv64": "0.14.42",
-        "esbuild-linux-s390x": "0.14.42",
-        "esbuild-netbsd-64": "0.14.42",
-        "esbuild-openbsd-64": "0.14.42",
-        "esbuild-sunos-64": "0.14.42",
-        "esbuild-windows-32": "0.14.42",
-        "esbuild-windows-64": "0.14.42",
-        "esbuild-windows-arm64": "0.14.42"
+        "esbuild-android-64": "0.14.51",
+        "esbuild-android-arm64": "0.14.51",
+        "esbuild-darwin-64": "0.14.51",
+        "esbuild-darwin-arm64": "0.14.51",
+        "esbuild-freebsd-64": "0.14.51",
+        "esbuild-freebsd-arm64": "0.14.51",
+        "esbuild-linux-32": "0.14.51",
+        "esbuild-linux-64": "0.14.51",
+        "esbuild-linux-arm": "0.14.51",
+        "esbuild-linux-arm64": "0.14.51",
+        "esbuild-linux-mips64le": "0.14.51",
+        "esbuild-linux-ppc64le": "0.14.51",
+        "esbuild-linux-riscv64": "0.14.51",
+        "esbuild-linux-s390x": "0.14.51",
+        "esbuild-netbsd-64": "0.14.51",
+        "esbuild-openbsd-64": "0.14.51",
+        "esbuild-sunos-64": "0.14.51",
+        "esbuild-windows-32": "0.14.51",
+        "esbuild-windows-64": "0.14.51",
+        "esbuild-windows-arm64": "0.14.51"
       }
     },
     "node_modules/esbuild-android-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.42.tgz",
-      "integrity": "sha512-P4Y36VUtRhK/zivqGVMqhptSrFILAGlYp0Z8r9UQqHJ3iWztRCNWnlBzD9HRx0DbueXikzOiwyOri+ojAFfW6A==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.51.tgz",
+      "integrity": "sha512-6FOuKTHnC86dtrKDmdSj2CkcKF8PnqkaIXqvgydqfJmqBazCPdw+relrMlhGjkvVdiiGV70rpdnyFmA65ekBCQ==",
       "cpu": [
         "x64"
       ],
@@ -396,9 +520,9 @@
       }
     },
     "node_modules/esbuild-android-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.42.tgz",
-      "integrity": "sha512-0cOqCubq+RWScPqvtQdjXG3Czb3AWI2CaKw3HeXry2eoA2rrPr85HF7IpdU26UWdBXgPYtlTN1LUiuXbboROhg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.51.tgz",
+      "integrity": "sha512-vBtp//5VVkZWmYYvHsqBRCMMi1MzKuMIn5XDScmnykMTu9+TD9v0NMEDqQxvtFToeYmojdo5UCV2vzMQWJcJ4A==",
       "cpu": [
         "arm64"
       ],
@@ -412,9 +536,9 @@
       }
     },
     "node_modules/esbuild-darwin-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.42.tgz",
-      "integrity": "sha512-ipiBdCA3ZjYgRfRLdQwP82rTiv/YVMtW36hTvAN5ZKAIfxBOyPXY7Cejp3bMXWgzKD8B6O+zoMzh01GZsCuEIA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.51.tgz",
+      "integrity": "sha512-YFmXPIOvuagDcwCejMRtCDjgPfnDu+bNeh5FU2Ryi68ADDVlWEpbtpAbrtf/lvFTWPexbgyKgzppNgsmLPr8PA==",
       "cpu": [
         "x64"
       ],
@@ -428,9 +552,9 @@
       }
     },
     "node_modules/esbuild-darwin-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.42.tgz",
-      "integrity": "sha512-bU2tHRqTPOaoH/4m0zYHbFWpiYDmaA0gt90/3BMEFaM0PqVK/a6MA2V/ypV5PO0v8QxN6gH5hBPY4YJ2lopXgA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.51.tgz",
+      "integrity": "sha512-juYD0QnSKwAMfzwKdIF6YbueXzS6N7y4GXPDeDkApz/1RzlT42mvX9jgNmyOlWKN7YzQAYbcUEJmZJYQGdf2ow==",
       "cpu": [
         "arm64"
       ],
@@ -444,9 +568,9 @@
       }
     },
     "node_modules/esbuild-freebsd-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.42.tgz",
-      "integrity": "sha512-75h1+22Ivy07+QvxHyhVqOdekupiTZVLN1PMwCDonAqyXd8TVNJfIRFrdL8QmSJrOJJ5h8H1I9ETyl2L8LQDaw==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.51.tgz",
+      "integrity": "sha512-cLEI/aXjb6vo5O2Y8rvVSQ7smgLldwYY5xMxqh/dQGfWO+R1NJOFsiax3IS4Ng300SVp7Gz3czxT6d6qf2cw0g==",
       "cpu": [
         "x64"
       ],
@@ -460,9 +584,9 @@
       }
     },
     "node_modules/esbuild-freebsd-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.42.tgz",
-      "integrity": "sha512-W6Jebeu5TTDQMJUJVarEzRU9LlKpNkPBbjqSu+GUPTHDCly5zZEQq9uHkmHHl7OKm+mQ2zFySN83nmfCeZCyNA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.51.tgz",
+      "integrity": "sha512-TcWVw/rCL2F+jUgRkgLa3qltd5gzKjIMGhkVybkjk6PJadYInPtgtUBp1/hG+mxyigaT7ib+od1Xb84b+L+1Mg==",
       "cpu": [
         "arm64"
       ],
@@ -476,9 +600,9 @@
       }
     },
     "node_modules/esbuild-linux-32": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.42.tgz",
-      "integrity": "sha512-Ooy/Bj+mJ1z4jlWcK5Dl6SlPlCgQB9zg1UrTCeY8XagvuWZ4qGPyYEWGkT94HUsRi2hKsXvcs6ThTOjBaJSMfg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.51.tgz",
+      "integrity": "sha512-RFqpyC5ChyWrjx8Xj2K0EC1aN0A37H6OJfmUXIASEqJoHcntuV3j2Efr9RNmUhMfNE6yEj2VpYuDteZLGDMr0w==",
       "cpu": [
         "ia32"
       ],
@@ -492,9 +616,9 @@
       }
     },
     "node_modules/esbuild-linux-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.42.tgz",
-      "integrity": "sha512-2L0HbzQfbTuemUWfVqNIjOfaTRt9zsvjnme6lnr7/MO9toz/MJ5tZhjqrG6uDWDxhsaHI2/nsDgrv8uEEN2eoA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.51.tgz",
+      "integrity": "sha512-dxjhrqo5i7Rq6DXwz5v+MEHVs9VNFItJmHBe1CxROWNf4miOGoQhqSG8StStbDkQ1Mtobg6ng+4fwByOhoQoeA==",
       "cpu": [
         "x64"
       ],
@@ -508,9 +632,9 @@
       }
     },
     "node_modules/esbuild-linux-arm": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.42.tgz",
-      "integrity": "sha512-STq69yzCMhdRaWnh29UYrLSr/qaWMm/KqwaRF1pMEK7kDiagaXhSL1zQGXbYv94GuGY/zAwzK98+6idCMUOOCg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.51.tgz",
+      "integrity": "sha512-LsJynDxYF6Neg7ZC7748yweCDD+N8ByCv22/7IAZglIEniEkqdF4HCaa49JNDLw1UQGlYuhOB8ZT/MmcSWzcWg==",
       "cpu": [
         "arm"
       ],
@@ -524,9 +648,9 @@
       }
     },
     "node_modules/esbuild-linux-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.42.tgz",
-      "integrity": "sha512-c3Ug3e9JpVr8jAcfbhirtpBauLxzYPpycjWulD71CF6ZSY26tvzmXMJYooQ2YKqDY4e/fPu5K8bm7MiXMnyxuA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.51.tgz",
+      "integrity": "sha512-D9rFxGutoqQX3xJPxqd6o+kvYKeIbM0ifW2y0bgKk5HPgQQOo2k9/2Vpto3ybGYaFPCE5qTGtqQta9PoP6ZEzw==",
       "cpu": [
         "arm64"
       ],
@@ -540,9 +664,9 @@
       }
     },
     "node_modules/esbuild-linux-mips64le": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.42.tgz",
-      "integrity": "sha512-QuvpHGbYlkyXWf2cGm51LBCHx6eUakjaSrRpUqhPwjh/uvNUYvLmz2LgPTTPwCqaKt0iwL+OGVL0tXA5aDbAbg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.51.tgz",
+      "integrity": "sha512-vS54wQjy4IinLSlb5EIlLoln8buh1yDgliP4CuEHumrPk4PvvP4kTRIG4SzMXm6t19N0rIfT4bNdAxzJLg2k6A==",
       "cpu": [
         "mips64el"
       ],
@@ -556,9 +680,9 @@
       }
     },
     "node_modules/esbuild-linux-ppc64le": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.42.tgz",
-      "integrity": "sha512-8ohIVIWDbDT+i7lCx44YCyIRrOW1MYlks9fxTo0ME2LS/fxxdoJBwHWzaDYhjvf8kNpA+MInZvyOEAGoVDrMHg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.51.tgz",
+      "integrity": "sha512-xcdd62Y3VfGoyphNP/aIV9LP+RzFw5M5Z7ja+zdpQHHvokJM7d0rlDRMN+iSSwvUymQkqZO+G/xjb4/75du8BQ==",
       "cpu": [
         "ppc64"
       ],
@@ -572,9 +696,9 @@
       }
     },
     "node_modules/esbuild-linux-riscv64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.42.tgz",
-      "integrity": "sha512-DzDqK3TuoXktPyG1Lwx7vhaF49Onv3eR61KwQyxYo4y5UKTpL3NmuarHSIaSVlTFDDpcIajCDwz5/uwKLLgKiQ==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.51.tgz",
+      "integrity": "sha512-syXHGak9wkAnFz0gMmRBoy44JV0rp4kVCEA36P5MCeZcxFq8+fllBC2t6sKI23w3qd8Vwo9pTADCgjTSf3L3rA==",
       "cpu": [
         "riscv64"
       ],
@@ -588,9 +712,9 @@
       }
     },
     "node_modules/esbuild-linux-s390x": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.42.tgz",
-      "integrity": "sha512-YFRhPCxl8nb//Wn6SiS5pmtplBi4z9yC2gLrYoYI/tvwuB1jldir9r7JwAGy1Ck4D7sE7wBN9GFtUUX/DLdcEQ==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.51.tgz",
+      "integrity": "sha512-kFAJY3dv+Wq8o28K/C7xkZk/X34rgTwhknSsElIqoEo8armCOjMJ6NsMxm48KaWY2h2RUYGtQmr+RGuUPKBhyw==",
       "cpu": [
         "s390x"
       ],
@@ -604,9 +728,9 @@
       }
     },
     "node_modules/esbuild-netbsd-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.42.tgz",
-      "integrity": "sha512-QYSD2k+oT9dqB/4eEM9c+7KyNYsIPgzYOSrmfNGDIyJrbT1d+CFVKvnKahDKNJLfOYj8N4MgyFaU9/Ytc6w5Vw==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.51.tgz",
+      "integrity": "sha512-ZZBI7qrR1FevdPBVHz/1GSk1x5GDL/iy42Zy8+neEm/HA7ma+hH/bwPEjeHXKWUDvM36CZpSL/fn1/y9/Hb+1A==",
       "cpu": [
         "x64"
       ],
@@ -620,9 +744,9 @@
       }
     },
     "node_modules/esbuild-openbsd-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.42.tgz",
-      "integrity": "sha512-M2meNVIKWsm2HMY7+TU9AxM7ZVwI9havdsw6m/6EzdXysyCFFSoaTQ/Jg03izjCsK17FsVRHqRe26Llj6x0MNA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.51.tgz",
+      "integrity": "sha512-7R1/p39M+LSVQVgDVlcY1KKm6kFKjERSX1lipMG51NPcspJD1tmiZSmmBXoY5jhHIu6JL1QkFDTx94gMYK6vfA==",
       "cpu": [
         "x64"
       ],
@@ -636,9 +760,9 @@
       }
     },
     "node_modules/esbuild-sunos-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.42.tgz",
-      "integrity": "sha512-uXV8TAZEw36DkgW8Ak3MpSJs1ofBb3Smkc/6pZ29sCAN1KzCAQzsje4sUwugf+FVicrHvlamCOlFZIXgct+iqQ==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.51.tgz",
+      "integrity": "sha512-HoHaCswHxLEYN8eBTtyO0bFEWvA3Kdb++hSQ/lLG7TyKF69TeSG0RNoBRAs45x/oCeWaTDntEZlYwAfQlhEtJA==",
       "cpu": [
         "x64"
       ],
@@ -652,9 +776,9 @@
       }
     },
     "node_modules/esbuild-windows-32": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.42.tgz",
-      "integrity": "sha512-4iw/8qWmRICWi9ZOnJJf9sYt6wmtp3hsN4TdI5NqgjfOkBVMxNdM9Vt3626G1Rda9ya2Q0hjQRD9W1o+m6Lz6g==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.51.tgz",
+      "integrity": "sha512-4rtwSAM35A07CBt1/X8RWieDj3ZUHQqUOaEo5ZBs69rt5WAFjP4aqCIobdqOy4FdhYw1yF8Z0xFBTyc9lgPtEg==",
       "cpu": [
         "ia32"
       ],
@@ -668,9 +792,9 @@
       }
     },
     "node_modules/esbuild-windows-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.42.tgz",
-      "integrity": "sha512-j3cdK+Y3+a5H0wHKmLGTJcq0+/2mMBHPWkItR3vytp/aUGD/ua/t2BLdfBIzbNN9nLCRL9sywCRpOpFMx3CxzA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.51.tgz",
+      "integrity": "sha512-HoN/5HGRXJpWODprGCgKbdMvrC3A2gqvzewu2eECRw2sYxOUoh2TV1tS+G7bHNapPGI79woQJGV6pFH7GH7qnA==",
       "cpu": [
         "x64"
       ],
@@ -684,9 +808,9 @@
       }
     },
     "node_modules/esbuild-windows-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.42.tgz",
-      "integrity": "sha512-+lRAARnF+hf8J0mN27ujO+VbhPbDqJ8rCcJKye4y7YZLV6C4n3pTRThAb388k/zqF5uM0lS5O201u0OqoWSicw==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.51.tgz",
+      "integrity": "sha512-JQDqPjuOH7o+BsKMSddMfmVJXrnYZxXDHsoLHc0xgmAZkOOCflRmC43q31pk79F9xuyWY45jDBPolb5ZgGOf9g==",
       "cpu": [
         "arm64"
       ],
@@ -1524,9 +1648,9 @@
       }
     },
     "node_modules/sass": {
-      "version": "1.52.1",
-      "resolved": "https://registry.npmjs.org/sass/-/sass-1.52.1.tgz",
-      "integrity": "sha512-fSzYTbr7z8oQnVJ3Acp9hV80dM1fkMN7mSD/25mpcct9F7FPBMOI8krEYALgU1aZoqGhQNhTPsuSmxjnIvAm4Q==",
+      "version": "1.54.0",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.0.tgz",
+      "integrity": "sha512-C4zp79GCXZfK0yoHZg+GxF818/aclhp9F48XBu/+bm9vXEVAYov9iU3FBVRMq3Hx3OA4jfKL+p2K9180mEh0xQ==",
       "dev": true,
       "dependencies": {
         "chokidar": ">=3.0.0 <4.0.0",
@@ -1602,9 +1726,9 @@
       }
     },
     "node_modules/snabbdom": {
-      "version": "3.5.0",
-      "resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-3.5.0.tgz",
-      "integrity": "sha512-Ff5BKG18KrrPuskHJlA9aujPHqEabItaDl96l7ZZndF4zt5AYSczz7ZjjgQAX5IBd5cd25lw9NfgX21yVUJ+9g==",
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-3.5.1.tgz",
+      "integrity": "sha512-wHMNIOjkm/YNE5EM3RCbr/+DVgPg6AqQAX1eOxO46zYNvCXjKP5Y865tqQj3EXnaMBjkxmQA5jFuDpDK/dbfiA==",
       "engines": {
         "node": ">=8.3.0"
       }
@@ -1733,6 +1857,11 @@
         "node": ">=4"
       }
     },
+    "node_modules/style-mod": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz",
+      "integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw=="
+    },
     "node_modules/supports-color": {
       "version": "5.5.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -1792,6 +1921,11 @@
         "spdx-expression-parse": "^3.0.0"
       }
     },
+    "node_modules/w3c-keyname": {
+      "version": "2.2.5",
+      "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.5.tgz",
+      "integrity": "sha512-WJrK7i6w+ULuZsGscCezbCH4Aev5U3xY87vnSimzzEgPQhb0Sa0a1rE3c2jtEwrFtSfi61Jefw3jI5/DD/3jbQ=="
+    },
     "node_modules/which": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
@@ -1897,6 +2031,105 @@
     }
   },
   "dependencies": {
+    "@codemirror/autocomplete": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.1.0.tgz",
+      "integrity": "sha512-wtO4O5WDyXhhCd4q4utDIDZxnQfmJ++3dGBCG9LMtI79+92OcA1DVk/n7BEupKmjIr8AzvptDz7YQ9ud6OkU+A==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "@codemirror/commands": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.0.1.tgz",
+      "integrity": "sha512-iNHDByicYqQjs0Wo1MKGfqNbMYMyhS9WV6EwMVwsHXImlFemgEUC+c5X22bXKBStN3qnwg4fArNZM+gkv22baQ==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "@codemirror/language": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz",
+      "integrity": "sha512-MC3svxuvIj0MRpFlGHxLS6vPyIdbTr2KKPEW46kCoCXw2ktb4NTkpkPBI/lSP/FoNXLCBJ0mrnUi1OoZxtpW1Q==",
+      "requires": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0",
+        "style-mod": "^4.0.0"
+      }
+    },
+    "@codemirror/legacy-modes": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.1.0.tgz",
+      "integrity": "sha512-V/PgGpndkZeTn3Hdlg/gd8MLFdyvTCIX+iwJzjUw5iNziWiNsAY8X0jvf7m3gSfxnKkNzmid6l0g4rYSpiDaCw==",
+      "requires": {
+        "@codemirror/language": "^6.0.0"
+      }
+    },
+    "@codemirror/lint": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.0.0.tgz",
+      "integrity": "sha512-nUUXcJW1Xp54kNs+a1ToPLK8MadO0rMTnJB8Zk4Z8gBdrN0kqV7uvUraU/T2yqg+grDNR38Vmy/MrhQN/RgwiA==",
+      "requires": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "crelt": "^1.0.5"
+      }
+    },
+    "@codemirror/search": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.0.1.tgz",
+      "integrity": "sha512-uOinkOrM+daMduCgMPomDfKLr7drGHB4jHl3Vq6xY2WRlL7MkNsBE0b+XHYa/Mee2npsJOgwvkW4n1lMFeBW2Q==",
+      "requires": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "crelt": "^1.0.5"
+      }
+    },
+    "@codemirror/state": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.1.0.tgz",
+      "integrity": "sha512-qbUr94DZTe6/V1VS7LDLz11rM/1t/nJxR1El4I6UaxDEdc0aZZvq6JCLJWiRmUf95NRAnDH6fhXn+PWp9wGCIg=="
+    },
+    "@codemirror/view": {
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.1.2.tgz",
+      "integrity": "sha512-puUydfKwfmOo+ixtuB+uN/ZpcteEYSnpjHmMaow1sOQhNICsKtGBup3i9ybVqyzDagARRYzSHTWjbdeHqmn31w==",
+      "requires": {
+        "@codemirror/state": "^6.0.0",
+        "style-mod": "^4.0.0",
+        "w3c-keyname": "^2.2.4"
+      }
+    },
+    "@lezer/common": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.0.tgz",
+      "integrity": "sha512-ohydQe+Hb+w4oMDvXzs8uuJd2NoA3D8YDcLiuDsLqH+yflDTPEpgCsWI3/6rH5C3BAedtH1/R51dxENldQceEA=="
+    },
+    "@lezer/highlight": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.0.0.tgz",
+      "integrity": "sha512-nsCnNtim90UKsB5YxoX65v3GEIw3iCHw9RM2DtdgkiqAbKh9pCdvi8AWNwkYf10Lu6fxNhXPpkpHbW6mihhvJA==",
+      "requires": {
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "@lezer/lr": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.2.0.tgz",
+      "integrity": "sha512-TgEpfm9br2SX8JwtwKT8HsQZKuFkLRg6g+IRxObk9nVKQLKnkP3oMh+QGcTBL9GQsfQ2ADtKPbj2iGSMf3ytiA==",
+      "requires": {
+        "@lezer/common": "^1.0.0"
+      }
+    },
     "ansi-regex": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
@@ -2035,9 +2268,18 @@
       }
     },
     "codemirror": {
-      "version": "5.65.5",
-      "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.5.tgz",
-      "integrity": "sha512-HNyhvGLnYz5c+kIsB9QKVitiZUevha3ovbIYaQiGzKo7ECSL/elWD9RXt3JgNr0NdnyqE9/Rc/7uLfkJQL638w=="
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
+      "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
+      "requires": {
+        "@codemirror/autocomplete": "^6.0.0",
+        "@codemirror/commands": "^6.0.0",
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/lint": "^6.0.0",
+        "@codemirror/search": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0"
+      }
     },
     "color-convert": {
       "version": "1.9.3",
@@ -2060,6 +2302,11 @@
       "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
       "dev": true
     },
+    "crelt": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.5.tgz",
+      "integrity": "sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA=="
+    },
     "cross-spawn": {
       "version": "6.0.5",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -2158,170 +2405,170 @@
       }
     },
     "esbuild": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.42.tgz",
-      "integrity": "sha512-V0uPZotCEHokJdNqyozH6qsaQXqmZEOiZWrXnds/zaH/0SyrIayRXWRB98CENO73MIZ9T3HBIOsmds5twWtmgw==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.51.tgz",
+      "integrity": "sha512-+CvnDitD7Q5sT7F+FM65sWkF8wJRf+j9fPcprxYV4j+ohmzVj2W7caUqH2s5kCaCJAfcAICjSlKhDCcvDpU7nw==",
       "dev": true,
       "requires": {
-        "esbuild-android-64": "0.14.42",
-        "esbuild-android-arm64": "0.14.42",
-        "esbuild-darwin-64": "0.14.42",
-        "esbuild-darwin-arm64": "0.14.42",
-        "esbuild-freebsd-64": "0.14.42",
-        "esbuild-freebsd-arm64": "0.14.42",
-        "esbuild-linux-32": "0.14.42",
-        "esbuild-linux-64": "0.14.42",
-        "esbuild-linux-arm": "0.14.42",
-        "esbuild-linux-arm64": "0.14.42",
-        "esbuild-linux-mips64le": "0.14.42",
-        "esbuild-linux-ppc64le": "0.14.42",
-        "esbuild-linux-riscv64": "0.14.42",
-        "esbuild-linux-s390x": "0.14.42",
-        "esbuild-netbsd-64": "0.14.42",
-        "esbuild-openbsd-64": "0.14.42",
-        "esbuild-sunos-64": "0.14.42",
-        "esbuild-windows-32": "0.14.42",
-        "esbuild-windows-64": "0.14.42",
-        "esbuild-windows-arm64": "0.14.42"
+        "esbuild-android-64": "0.14.51",
+        "esbuild-android-arm64": "0.14.51",
+        "esbuild-darwin-64": "0.14.51",
+        "esbuild-darwin-arm64": "0.14.51",
+        "esbuild-freebsd-64": "0.14.51",
+        "esbuild-freebsd-arm64": "0.14.51",
+        "esbuild-linux-32": "0.14.51",
+        "esbuild-linux-64": "0.14.51",
+        "esbuild-linux-arm": "0.14.51",
+        "esbuild-linux-arm64": "0.14.51",
+        "esbuild-linux-mips64le": "0.14.51",
+        "esbuild-linux-ppc64le": "0.14.51",
+        "esbuild-linux-riscv64": "0.14.51",
+        "esbuild-linux-s390x": "0.14.51",
+        "esbuild-netbsd-64": "0.14.51",
+        "esbuild-openbsd-64": "0.14.51",
+        "esbuild-sunos-64": "0.14.51",
+        "esbuild-windows-32": "0.14.51",
+        "esbuild-windows-64": "0.14.51",
+        "esbuild-windows-arm64": "0.14.51"
       }
     },
     "esbuild-android-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.42.tgz",
-      "integrity": "sha512-P4Y36VUtRhK/zivqGVMqhptSrFILAGlYp0Z8r9UQqHJ3iWztRCNWnlBzD9HRx0DbueXikzOiwyOri+ojAFfW6A==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.51.tgz",
+      "integrity": "sha512-6FOuKTHnC86dtrKDmdSj2CkcKF8PnqkaIXqvgydqfJmqBazCPdw+relrMlhGjkvVdiiGV70rpdnyFmA65ekBCQ==",
       "dev": true,
       "optional": true
     },
     "esbuild-android-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.42.tgz",
-      "integrity": "sha512-0cOqCubq+RWScPqvtQdjXG3Czb3AWI2CaKw3HeXry2eoA2rrPr85HF7IpdU26UWdBXgPYtlTN1LUiuXbboROhg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.51.tgz",
+      "integrity": "sha512-vBtp//5VVkZWmYYvHsqBRCMMi1MzKuMIn5XDScmnykMTu9+TD9v0NMEDqQxvtFToeYmojdo5UCV2vzMQWJcJ4A==",
       "dev": true,
       "optional": true
     },
     "esbuild-darwin-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.42.tgz",
-      "integrity": "sha512-ipiBdCA3ZjYgRfRLdQwP82rTiv/YVMtW36hTvAN5ZKAIfxBOyPXY7Cejp3bMXWgzKD8B6O+zoMzh01GZsCuEIA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.51.tgz",
+      "integrity": "sha512-YFmXPIOvuagDcwCejMRtCDjgPfnDu+bNeh5FU2Ryi68ADDVlWEpbtpAbrtf/lvFTWPexbgyKgzppNgsmLPr8PA==",
       "dev": true,
       "optional": true
     },
     "esbuild-darwin-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.42.tgz",
-      "integrity": "sha512-bU2tHRqTPOaoH/4m0zYHbFWpiYDmaA0gt90/3BMEFaM0PqVK/a6MA2V/ypV5PO0v8QxN6gH5hBPY4YJ2lopXgA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.51.tgz",
+      "integrity": "sha512-juYD0QnSKwAMfzwKdIF6YbueXzS6N7y4GXPDeDkApz/1RzlT42mvX9jgNmyOlWKN7YzQAYbcUEJmZJYQGdf2ow==",
       "dev": true,
       "optional": true
     },
     "esbuild-freebsd-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.42.tgz",
-      "integrity": "sha512-75h1+22Ivy07+QvxHyhVqOdekupiTZVLN1PMwCDonAqyXd8TVNJfIRFrdL8QmSJrOJJ5h8H1I9ETyl2L8LQDaw==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.51.tgz",
+      "integrity": "sha512-cLEI/aXjb6vo5O2Y8rvVSQ7smgLldwYY5xMxqh/dQGfWO+R1NJOFsiax3IS4Ng300SVp7Gz3czxT6d6qf2cw0g==",
       "dev": true,
       "optional": true
     },
     "esbuild-freebsd-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.42.tgz",
-      "integrity": "sha512-W6Jebeu5TTDQMJUJVarEzRU9LlKpNkPBbjqSu+GUPTHDCly5zZEQq9uHkmHHl7OKm+mQ2zFySN83nmfCeZCyNA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.51.tgz",
+      "integrity": "sha512-TcWVw/rCL2F+jUgRkgLa3qltd5gzKjIMGhkVybkjk6PJadYInPtgtUBp1/hG+mxyigaT7ib+od1Xb84b+L+1Mg==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-32": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.42.tgz",
-      "integrity": "sha512-Ooy/Bj+mJ1z4jlWcK5Dl6SlPlCgQB9zg1UrTCeY8XagvuWZ4qGPyYEWGkT94HUsRi2hKsXvcs6ThTOjBaJSMfg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.51.tgz",
+      "integrity": "sha512-RFqpyC5ChyWrjx8Xj2K0EC1aN0A37H6OJfmUXIASEqJoHcntuV3j2Efr9RNmUhMfNE6yEj2VpYuDteZLGDMr0w==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.42.tgz",
-      "integrity": "sha512-2L0HbzQfbTuemUWfVqNIjOfaTRt9zsvjnme6lnr7/MO9toz/MJ5tZhjqrG6uDWDxhsaHI2/nsDgrv8uEEN2eoA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.51.tgz",
+      "integrity": "sha512-dxjhrqo5i7Rq6DXwz5v+MEHVs9VNFItJmHBe1CxROWNf4miOGoQhqSG8StStbDkQ1Mtobg6ng+4fwByOhoQoeA==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-arm": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.42.tgz",
-      "integrity": "sha512-STq69yzCMhdRaWnh29UYrLSr/qaWMm/KqwaRF1pMEK7kDiagaXhSL1zQGXbYv94GuGY/zAwzK98+6idCMUOOCg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.51.tgz",
+      "integrity": "sha512-LsJynDxYF6Neg7ZC7748yweCDD+N8ByCv22/7IAZglIEniEkqdF4HCaa49JNDLw1UQGlYuhOB8ZT/MmcSWzcWg==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.42.tgz",
-      "integrity": "sha512-c3Ug3e9JpVr8jAcfbhirtpBauLxzYPpycjWulD71CF6ZSY26tvzmXMJYooQ2YKqDY4e/fPu5K8bm7MiXMnyxuA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.51.tgz",
+      "integrity": "sha512-D9rFxGutoqQX3xJPxqd6o+kvYKeIbM0ifW2y0bgKk5HPgQQOo2k9/2Vpto3ybGYaFPCE5qTGtqQta9PoP6ZEzw==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-mips64le": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.42.tgz",
-      "integrity": "sha512-QuvpHGbYlkyXWf2cGm51LBCHx6eUakjaSrRpUqhPwjh/uvNUYvLmz2LgPTTPwCqaKt0iwL+OGVL0tXA5aDbAbg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.51.tgz",
+      "integrity": "sha512-vS54wQjy4IinLSlb5EIlLoln8buh1yDgliP4CuEHumrPk4PvvP4kTRIG4SzMXm6t19N0rIfT4bNdAxzJLg2k6A==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-ppc64le": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.42.tgz",
-      "integrity": "sha512-8ohIVIWDbDT+i7lCx44YCyIRrOW1MYlks9fxTo0ME2LS/fxxdoJBwHWzaDYhjvf8kNpA+MInZvyOEAGoVDrMHg==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.51.tgz",
+      "integrity": "sha512-xcdd62Y3VfGoyphNP/aIV9LP+RzFw5M5Z7ja+zdpQHHvokJM7d0rlDRMN+iSSwvUymQkqZO+G/xjb4/75du8BQ==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-riscv64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.42.tgz",
-      "integrity": "sha512-DzDqK3TuoXktPyG1Lwx7vhaF49Onv3eR61KwQyxYo4y5UKTpL3NmuarHSIaSVlTFDDpcIajCDwz5/uwKLLgKiQ==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.51.tgz",
+      "integrity": "sha512-syXHGak9wkAnFz0gMmRBoy44JV0rp4kVCEA36P5MCeZcxFq8+fllBC2t6sKI23w3qd8Vwo9pTADCgjTSf3L3rA==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-s390x": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.42.tgz",
-      "integrity": "sha512-YFRhPCxl8nb//Wn6SiS5pmtplBi4z9yC2gLrYoYI/tvwuB1jldir9r7JwAGy1Ck4D7sE7wBN9GFtUUX/DLdcEQ==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.51.tgz",
+      "integrity": "sha512-kFAJY3dv+Wq8o28K/C7xkZk/X34rgTwhknSsElIqoEo8armCOjMJ6NsMxm48KaWY2h2RUYGtQmr+RGuUPKBhyw==",
       "dev": true,
       "optional": true
     },
     "esbuild-netbsd-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.42.tgz",
-      "integrity": "sha512-QYSD2k+oT9dqB/4eEM9c+7KyNYsIPgzYOSrmfNGDIyJrbT1d+CFVKvnKahDKNJLfOYj8N4MgyFaU9/Ytc6w5Vw==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.51.tgz",
+      "integrity": "sha512-ZZBI7qrR1FevdPBVHz/1GSk1x5GDL/iy42Zy8+neEm/HA7ma+hH/bwPEjeHXKWUDvM36CZpSL/fn1/y9/Hb+1A==",
       "dev": true,
       "optional": true
     },
     "esbuild-openbsd-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.42.tgz",
-      "integrity": "sha512-M2meNVIKWsm2HMY7+TU9AxM7ZVwI9havdsw6m/6EzdXysyCFFSoaTQ/Jg03izjCsK17FsVRHqRe26Llj6x0MNA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.51.tgz",
+      "integrity": "sha512-7R1/p39M+LSVQVgDVlcY1KKm6kFKjERSX1lipMG51NPcspJD1tmiZSmmBXoY5jhHIu6JL1QkFDTx94gMYK6vfA==",
       "dev": true,
       "optional": true
     },
     "esbuild-sunos-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.42.tgz",
-      "integrity": "sha512-uXV8TAZEw36DkgW8Ak3MpSJs1ofBb3Smkc/6pZ29sCAN1KzCAQzsje4sUwugf+FVicrHvlamCOlFZIXgct+iqQ==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.51.tgz",
+      "integrity": "sha512-HoHaCswHxLEYN8eBTtyO0bFEWvA3Kdb++hSQ/lLG7TyKF69TeSG0RNoBRAs45x/oCeWaTDntEZlYwAfQlhEtJA==",
       "dev": true,
       "optional": true
     },
     "esbuild-windows-32": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.42.tgz",
-      "integrity": "sha512-4iw/8qWmRICWi9ZOnJJf9sYt6wmtp3hsN4TdI5NqgjfOkBVMxNdM9Vt3626G1Rda9ya2Q0hjQRD9W1o+m6Lz6g==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.51.tgz",
+      "integrity": "sha512-4rtwSAM35A07CBt1/X8RWieDj3ZUHQqUOaEo5ZBs69rt5WAFjP4aqCIobdqOy4FdhYw1yF8Z0xFBTyc9lgPtEg==",
       "dev": true,
       "optional": true
     },
     "esbuild-windows-64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.42.tgz",
-      "integrity": "sha512-j3cdK+Y3+a5H0wHKmLGTJcq0+/2mMBHPWkItR3vytp/aUGD/ua/t2BLdfBIzbNN9nLCRL9sywCRpOpFMx3CxzA==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.51.tgz",
+      "integrity": "sha512-HoN/5HGRXJpWODprGCgKbdMvrC3A2gqvzewu2eECRw2sYxOUoh2TV1tS+G7bHNapPGI79woQJGV6pFH7GH7qnA==",
       "dev": true,
       "optional": true
     },
     "esbuild-windows-arm64": {
-      "version": "0.14.42",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.42.tgz",
-      "integrity": "sha512-+lRAARnF+hf8J0mN27ujO+VbhPbDqJ8rCcJKye4y7YZLV6C4n3pTRThAb388k/zqF5uM0lS5O201u0OqoWSicw==",
+      "version": "0.14.51",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.51.tgz",
+      "integrity": "sha512-JQDqPjuOH7o+BsKMSddMfmVJXrnYZxXDHsoLHc0xgmAZkOOCflRmC43q31pk79F9xuyWY45jDBPolb5ZgGOf9g==",
       "dev": true,
       "optional": true
     },
@@ -2922,9 +3169,9 @@
       }
     },
     "sass": {
-      "version": "1.52.1",
-      "resolved": "https://registry.npmjs.org/sass/-/sass-1.52.1.tgz",
-      "integrity": "sha512-fSzYTbr7z8oQnVJ3Acp9hV80dM1fkMN7mSD/25mpcct9F7FPBMOI8krEYALgU1aZoqGhQNhTPsuSmxjnIvAm4Q==",
+      "version": "1.54.0",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.0.tgz",
+      "integrity": "sha512-C4zp79GCXZfK0yoHZg+GxF818/aclhp9F48XBu/+bm9vXEVAYov9iU3FBVRMq3Hx3OA4jfKL+p2K9180mEh0xQ==",
       "dev": true,
       "requires": {
         "chokidar": ">=3.0.0 <4.0.0",
@@ -2982,9 +3229,9 @@
       }
     },
     "snabbdom": {
-      "version": "3.5.0",
-      "resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-3.5.0.tgz",
-      "integrity": "sha512-Ff5BKG18KrrPuskHJlA9aujPHqEabItaDl96l7ZZndF4zt5AYSczz7ZjjgQAX5IBd5cd25lw9NfgX21yVUJ+9g=="
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-3.5.1.tgz",
+      "integrity": "sha512-wHMNIOjkm/YNE5EM3RCbr/+DVgPg6AqQAX1eOxO46zYNvCXjKP5Y865tqQj3EXnaMBjkxmQA5jFuDpDK/dbfiA=="
     },
     "sortablejs": {
       "version": "1.15.0",
@@ -3086,6 +3333,11 @@
       "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
       "dev": true
     },
+    "style-mod": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz",
+      "integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw=="
+    },
     "supports-color": {
       "version": "5.5.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -3136,6 +3388,11 @@
         "spdx-expression-parse": "^3.0.0"
       }
     },
+    "w3c-keyname": {
+      "version": "2.2.5",
+      "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.5.tgz",
+      "integrity": "sha512-WJrK7i6w+ULuZsGscCezbCH4Aev5U3xY87vnSimzzEgPQhb0Sa0a1rE3c2jtEwrFtSfi61Jefw3jI5/DD/3jbQ=="
+    },
     "which": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
diff --git a/package.json b/package.json
index 9a2f66448..8407ffc77 100644
--- a/package.json
+++ b/package.json
@@ -16,19 +16,24 @@
   },
   "devDependencies": {
     "chokidar-cli": "^3.0",
-    "esbuild": "0.14.42",
+    "esbuild": "0.14.51",
     "livereload": "^0.9.3",
     "npm-run-all": "^4.1.5",
     "punycode": "^2.1.1",
-    "sass": "^1.52.1"
+    "sass": "^1.54.0"
   },
   "dependencies": {
+    "@codemirror/commands": "^6.0.1",
+    "@codemirror/language": "^6.2.1",
+    "@codemirror/legacy-modes": "^6.1.0",
+    "@codemirror/state": "^6.1.0",
+    "@codemirror/view": "^6.1.2",
     "clipboard": "^2.0.11",
-    "codemirror": "^5.65.5",
+    "codemirror": "^6.0.1",
     "dropzone": "^5.9.3",
     "markdown-it": "^13.0.1",
     "markdown-it-task-lists": "^2.1.1",
-    "snabbdom": "^3.5.0",
+    "snabbdom": "^3.5.1",
     "sortablejs": "^1.15.0"
   }
 }
diff --git a/resources/js/code.mjs b/resources/js/code/index.mjs
similarity index 55%
rename from resources/js/code.mjs
rename to resources/js/code/index.mjs
index eca941f1c..ff60cbff5 100644
--- a/resources/js/code.mjs
+++ b/resources/js/code/index.mjs
@@ -1,106 +1,10 @@
-import CodeMirror from "codemirror";
+import {EditorView} from "@codemirror/view"
+// import {EditorState} from "@codemirror/state"
 import Clipboard from "clipboard/dist/clipboard.min";
 
 // Modes
-import 'codemirror/mode/css/css';
-import 'codemirror/mode/clike/clike';
-import 'codemirror/mode/diff/diff';
-import 'codemirror/mode/fortran/fortran';
-import 'codemirror/mode/go/go';
-import 'codemirror/mode/haskell/haskell';
-import 'codemirror/mode/htmlmixed/htmlmixed';
-import 'codemirror/mode/javascript/javascript';
-import 'codemirror/mode/julia/julia';
-import 'codemirror/mode/lua/lua';
-import 'codemirror/mode/markdown/markdown';
-import 'codemirror/mode/mllike/mllike';
-import 'codemirror/mode/nginx/nginx';
-import 'codemirror/mode/perl/perl';
-import 'codemirror/mode/pascal/pascal';
-import 'codemirror/mode/php/php';
-import 'codemirror/mode/powershell/powershell';
-import 'codemirror/mode/properties/properties';
-import 'codemirror/mode/python/python';
-import 'codemirror/mode/ruby/ruby';
-import 'codemirror/mode/rust/rust';
-import 'codemirror/mode/shell/shell';
-import 'codemirror/mode/sql/sql';
-import 'codemirror/mode/stex/stex';
-import 'codemirror/mode/toml/toml';
-import 'codemirror/mode/vb/vb';
-import 'codemirror/mode/vbscript/vbscript';
-import 'codemirror/mode/xml/xml';
-import 'codemirror/mode/yaml/yaml';
-
-// Addons
-import 'codemirror/addon/scroll/scrollpastend';
-
-// Mapping of possible languages or formats from user input to their codemirror modes.
-// Value can be a mode string or a function that will receive the code content & return the mode string.
-// The function option is used in the event the exact mode could be dynamic depending on the code.
-const modeMap = {
-    bash: 'shell',
-    css: 'css',
-    c: 'text/x-csrc',
-    java: 'text/x-java',
-    scala: 'text/x-scala',
-    kotlin: 'text/x-kotlin',
-    'c++': 'text/x-c++src',
-    'c#': 'text/x-csharp',
-    csharp: 'text/x-csharp',
-    diff: 'diff',
-    for: 'fortran',
-    fortran: 'fortran',
-    'f#': 'text/x-fsharp',
-    fsharp: 'text/x-fsharp',
-    go: 'go',
-    haskell: 'haskell',
-    hs: 'haskell',
-    html: 'htmlmixed',
-    ini: 'properties',
-    javascript: 'text/javascript',
-    json: 'application/json',
-    js: 'text/javascript',
-    jl: 'text/x-julia',
-    julia: 'text/x-julia',
-    latex: 'text/x-stex',
-    lua: 'lua',
-    md: 'markdown',
-    mdown: 'markdown',
-    markdown: 'markdown',
-    ml: 'mllike',
-    nginx: 'nginx',
-    perl: 'perl',
-    pl: 'perl',
-    powershell: 'powershell',
-    properties: 'properties',
-    ocaml: 'text/x-ocaml',
-    pascal: 'text/x-pascal',
-    pas: 'text/x-pascal',
-    php: (content) => {
-        return content.includes('<?php') ? 'php' : 'text/x-php';
-    },
-    py: 'python',
-    python: 'python',
-    ruby: 'ruby',
-    rust: 'rust',
-    rb: 'ruby',
-    rs: 'rust',
-    shell: 'shell',
-    sh: 'shell',
-    stext: 'text/x-stex',
-    toml: 'toml',
-    ts: 'text/typescript',
-    typescript: 'text/typescript',
-    sql: 'text/x-sql',
-    vbs: 'vbscript',
-    vbscript: 'vbscript',
-    'vb.net': 'text/x-vb',
-    vbnet: 'text/x-vb',
-    xml: 'xml',
-    yaml: 'yaml',
-    yml: 'yaml',
-};
+import {modes, modeMap, modesAsStreamLanguages} from "./modes";
+import {viewer} from "./setups.js";
 
 /**
  * Highlight pre elements on a page
@@ -138,17 +42,19 @@ function highlightElem(elem) {
         mode = getMode(langName, content);
     }
 
-    const cm = CodeMirror(function(elt) {
-        elem.parentNode.replaceChild(elt, elem);
-    }, {
-        value: content,
-        mode:  mode,
-        lineNumbers: true,
-        lineWrapping: false,
-        theme: getTheme(),
-        readOnly: true
+    const wrapper = document.createElement('div');
+    elem.parentNode.insertBefore(wrapper, elem);
+
+    const cm = new EditorView({
+        parent: wrapper,
+        doc: content,
+        extensions: viewer(),
     });
 
+    elem.remove();
+
+    // TODO - theme: getTheme(),
+    // TODO - mode,
     addCopyIcon(cm);
 }
 
@@ -157,24 +63,25 @@ function highlightElem(elem) {
  * @param cmInstance
  */
 function addCopyIcon(cmInstance) {
-    const copyIcon = `<svg viewBox="0 0 24 24" width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>`;
-    const copyButton = document.createElement('div');
-    copyButton.classList.add('CodeMirror-copy');
-    copyButton.innerHTML = copyIcon;
-    cmInstance.display.wrapper.appendChild(copyButton);
-
-    const clipboard = new Clipboard(copyButton, {
-        text: function(trigger) {
-            return cmInstance.getValue()
-        }
-    });
-
-    clipboard.on('success', event => {
-        copyButton.classList.add('success');
-        setTimeout(() => {
-            copyButton.classList.remove('success');
-        }, 240);
-    });
+    // TODO
+    // const copyIcon = `<svg viewBox="0 0 24 24" width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>`;
+    // const copyButton = document.createElement('div');
+    // copyButton.classList.add('CodeMirror-copy');
+    // copyButton.innerHTML = copyIcon;
+    // cmInstance.display.wrapper.appendChild(copyButton);
+    //
+    // const clipboard = new Clipboard(copyButton, {
+    //     text: function(trigger) {
+    //         return cmInstance.getValue()
+    //     }
+    // });
+    //
+    // clipboard.on('success', event => {
+    //     copyButton.classList.add('success');
+    //     setTimeout(() => {
+    //         copyButton.classList.remove('success');
+    //     }, 240);
+    // });
 }
 
 /**
diff --git a/resources/js/code/modes.js b/resources/js/code/modes.js
new file mode 100644
index 000000000..5a89255a5
--- /dev/null
+++ b/resources/js/code/modes.js
@@ -0,0 +1,134 @@
+import {StreamLanguage} from "@codemirror/language"
+
+import {css as langCss} from '@codemirror/legacy-modes/mode/css';
+import {clike as langClike} from '@codemirror/legacy-modes/mode/clike';
+import {diff as langDiff} from '@codemirror/legacy-modes/mode/diff';
+import {fortran as langFortran} from '@codemirror/legacy-modes/mode/fortran';
+import {go as langGo} from '@codemirror/legacy-modes/mode/go';
+import {haskell as langHaskell} from '@codemirror/legacy-modes/mode/haskell';
+// import {htmlmixed as langHtmlmixed} from '@codemirror/legacy-modes/mode/htmlmixed';
+import {javascript as langJavascript} from '@codemirror/legacy-modes/mode/javascript';
+import {julia as langJulia} from '@codemirror/legacy-modes/mode/julia';
+import {lua as langLua} from '@codemirror/legacy-modes/mode/lua';
+// import {markdown as langMarkdown} from '@codemirror/legacy-modes/mode/markdown';
+import {oCaml as langMllike} from '@codemirror/legacy-modes/mode/mllike';
+import {nginx as langNginx} from '@codemirror/legacy-modes/mode/nginx';
+import {perl as langPerl} from '@codemirror/legacy-modes/mode/perl';
+import {pascal as langPascal} from '@codemirror/legacy-modes/mode/pascal';
+// import {php as langPhp} from '@codemirror/legacy-modes/mode/php';
+import {powerShell as langPowershell} from '@codemirror/legacy-modes/mode/powershell';
+import {properties as langProperties} from '@codemirror/legacy-modes/mode/properties';
+import {python as langPython} from '@codemirror/legacy-modes/mode/python';
+import {ruby as langRuby} from '@codemirror/legacy-modes/mode/ruby';
+import {rust as langRust} from '@codemirror/legacy-modes/mode/rust';
+import {shell as langShell} from '@codemirror/legacy-modes/mode/shell';
+import {sql as langSql} from '@codemirror/legacy-modes/mode/sql';
+import {stex as langStex} from '@codemirror/legacy-modes/mode/stex';
+import {toml as langToml} from '@codemirror/legacy-modes/mode/toml';
+import {vb as langVb} from '@codemirror/legacy-modes/mode/vb';
+import {vbScript as langVbscript} from '@codemirror/legacy-modes/mode/vbscript';
+import {xml as langXml} from '@codemirror/legacy-modes/mode/xml';
+import {yaml as langYaml} from '@codemirror/legacy-modes/mode/yaml';
+
+export const modes = [
+    langCss,
+    langClike,
+    langDiff,
+    langFortran,
+    langGo,
+    langHaskell,
+    // langHtmlmixed,
+    langJavascript,
+    langJulia,
+    langLua,
+    // langMarkdown,
+    langMllike,
+    langNginx,
+    langPerl,
+    langPascal,
+    // langPhp,
+    langPowershell,
+    langProperties,
+    langPython,
+    langRuby,
+    langRust,
+    langShell,
+    langSql,
+    langStex,
+    langToml,
+    langVb,
+    langVbscript,
+    langXml,
+    langYaml,
+];
+
+// Mapping of possible languages or formats from user input to their codemirror modes.
+// Value can be a mode string or a function that will receive the code content & return the mode string.
+// The function option is used in the event the exact mode could be dynamic depending on the code.
+export const modeMap = {
+    bash: 'shell',
+    css: 'css',
+    c: 'text/x-csrc',
+    java: 'text/x-java',
+    scala: 'text/x-scala',
+    kotlin: 'text/x-kotlin',
+    'c++': 'text/x-c++src',
+    'c#': 'text/x-csharp',
+    csharp: 'text/x-csharp',
+    diff: 'diff',
+    for: 'fortran',
+    fortran: 'fortran',
+    'f#': 'text/x-fsharp',
+    fsharp: 'text/x-fsharp',
+    go: 'go',
+    haskell: 'haskell',
+    hs: 'haskell',
+    html: 'htmlmixed',
+    ini: 'properties',
+    javascript: 'text/javascript',
+    json: 'application/json',
+    js: 'text/javascript',
+    jl: 'text/x-julia',
+    julia: 'text/x-julia',
+    latex: 'text/x-stex',
+    lua: 'lua',
+    md: 'markdown',
+    mdown: 'markdown',
+    markdown: 'markdown',
+    ml: 'mllike',
+    nginx: 'nginx',
+    perl: 'perl',
+    pl: 'perl',
+    powershell: 'powershell',
+    properties: 'properties',
+    ocaml: 'text/x-ocaml',
+    pascal: 'text/x-pascal',
+    pas: 'text/x-pascal',
+    php: (content) => {
+        return content.includes('<?php') ? 'php' : 'text/x-php';
+    },
+    py: 'python',
+    python: 'python',
+    ruby: 'ruby',
+    rust: 'rust',
+    rb: 'ruby',
+    rs: 'rust',
+    shell: 'shell',
+    sh: 'shell',
+    stext: 'text/x-stex',
+    toml: 'toml',
+    ts: 'text/typescript',
+    typescript: 'text/typescript',
+    sql: 'text/x-sql',
+    vbs: 'vbscript',
+    vbscript: 'vbscript',
+    'vb.net': 'text/x-vb',
+    vbnet: 'text/x-vb',
+    xml: 'xml',
+    yaml: 'yaml',
+    yml: 'yaml',
+};
+
+export function modesAsStreamLanguages() {
+    return modes.map(mode => StreamLanguage.define(mode));
+}
\ No newline at end of file
diff --git a/resources/js/code/setups.js b/resources/js/code/setups.js
new file mode 100644
index 000000000..768d3a35d
--- /dev/null
+++ b/resources/js/code/setups.js
@@ -0,0 +1,32 @@
+
+import {keymap, highlightSpecialChars, drawSelection, highlightActiveLine, dropCursor,
+    rectangularSelection, lineNumbers, highlightActiveLineGutter} from "@codemirror/view"
+import {defaultHighlightStyle, syntaxHighlighting, bracketMatching,
+     foldKeymap} from "@codemirror/language"
+import {defaultKeymap, history, historyKeymap} from "@codemirror/commands"
+import {EditorState} from "@codemirror/state"
+
+import {modesAsStreamLanguages} from "./modes";
+
+
+export function viewer() {
+    return [
+        lineNumbers(),
+        highlightActiveLineGutter(),
+        highlightSpecialChars(),
+        history(),
+        drawSelection(),
+        dropCursor(),
+        syntaxHighlighting(defaultHighlightStyle, {fallback: true}),
+        bracketMatching(),
+        rectangularSelection(),
+        highlightActiveLine(),
+        keymap.of([
+            ...defaultKeymap,
+            ...historyKeymap,
+            ...foldKeymap,
+        ]),
+        EditorState.readOnly.of(true),
+        ...modesAsStreamLanguages(),
+    ];
+}
\ No newline at end of file