diff --git a/courseware-block/package-lock.json b/courseware-block/package-lock.json
index cc7ec7557edadf1db9ee1539b8adefa32ab48ae0..9f9faa4b26bc1e93bbd79a424c4ab05b710a04e6 100644
--- a/courseware-block/package-lock.json
+++ b/courseware-block/package-lock.json
@@ -9,7 +9,8 @@
             "version": "0.2.0",
             "license": "GPLv3",
             "dependencies": {
-                "axios": "^0.21.4"
+                "axios": "^0.21.4",
+                "vuex": "^3.6.2"
             },
             "devDependencies": {
                 "@types/offscreencanvas": "^2019.7.0",
@@ -453,7 +454,6 @@
             "version": "7.23.9",
             "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz",
             "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==",
-            "dev": true,
             "bin": {
                 "parser": "bin/babel-parser.js"
             },
@@ -5456,8 +5456,7 @@
         "node_modules/csstype": {
             "version": "3.1.3",
             "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
-            "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
-            "dev": true
+            "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
         },
         "node_modules/cyclist": {
             "version": "1.0.2",
@@ -9408,7 +9407,6 @@
             "version": "3.3.7",
             "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
             "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
-            "dev": true,
             "funding": [
                 {
                     "type": "github",
@@ -10983,7 +10981,7 @@
             "version": "2.8.8",
             "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
             "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
-            "dev": true,
+            "devOptional": true,
             "bin": {
                 "prettier": "bin-prettier.js"
             },
@@ -12271,7 +12269,6 @@
             "version": "0.6.1",
             "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
             "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-            "dev": true,
             "engines": {
                 "node": ">=0.10.0"
             }
@@ -12280,7 +12277,6 @@
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
             "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
-            "dev": true,
             "engines": {
                 "node": ">=0.10.0"
             }
@@ -13801,7 +13797,6 @@
             "resolved": "https://registry.npmjs.org/vue/-/vue-2.7.16.tgz",
             "integrity": "sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==",
             "deprecated": "Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details.",
-            "dev": true,
             "dependencies": {
                 "@vue/compiler-sfc": "2.7.16",
                 "csstype": "^3.1.0"
@@ -14033,7 +14028,6 @@
             "version": "2.7.16",
             "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.16.tgz",
             "integrity": "sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg==",
-            "dev": true,
             "dependencies": {
                 "@babel/parser": "^7.23.5",
                 "postcss": "^8.4.14",
@@ -14046,14 +14040,12 @@
         "node_modules/vue/node_modules/picocolors": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-            "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
-            "dev": true
+            "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
         },
         "node_modules/vue/node_modules/postcss": {
             "version": "8.4.35",
             "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
             "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==",
-            "dev": true,
             "funding": [
                 {
                     "type": "opencollective",
@@ -14077,6 +14069,14 @@
                 "node": "^10 || ^12 || >=14"
             }
         },
+        "node_modules/vuex": {
+            "version": "3.6.2",
+            "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz",
+            "integrity": "sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==",
+            "peerDependencies": {
+                "vue": "^2.0.0"
+            }
+        },
         "node_modules/watchpack": {
             "version": "1.7.5",
             "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
@@ -15433,8 +15433,7 @@
         "@babel/parser": {
             "version": "7.23.9",
             "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz",
-            "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==",
-            "dev": true
+            "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA=="
         },
         "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
             "version": "7.23.3",
@@ -19297,8 +19296,7 @@
         "csstype": {
             "version": "3.1.3",
             "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
-            "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
-            "dev": true
+            "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
         },
         "cyclist": {
             "version": "1.0.2",
@@ -22360,8 +22358,7 @@
         "nanoid": {
             "version": "3.3.7",
             "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
-            "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
-            "dev": true
+            "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="
         },
         "nanomatch": {
             "version": "1.2.13",
@@ -23665,7 +23662,7 @@
             "version": "2.8.8",
             "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
             "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
-            "dev": true
+            "devOptional": true
         },
         "pretty-error": {
             "version": "2.1.2",
@@ -24742,14 +24739,12 @@
         "source-map": {
             "version": "0.6.1",
             "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-            "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-            "dev": true
+            "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
         },
         "source-map-js": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
-            "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
-            "dev": true
+            "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
         },
         "source-map-resolve": {
             "version": "0.5.3",
@@ -25976,7 +25971,6 @@
             "version": "2.7.16",
             "resolved": "https://registry.npmjs.org/vue/-/vue-2.7.16.tgz",
             "integrity": "sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==",
-            "dev": true,
             "requires": {
                 "@vue/compiler-sfc": "2.7.16",
                 "csstype": "^3.1.0"
@@ -25986,7 +25980,6 @@
                     "version": "2.7.16",
                     "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.16.tgz",
                     "integrity": "sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg==",
-                    "dev": true,
                     "requires": {
                         "@babel/parser": "^7.23.5",
                         "postcss": "^8.4.14",
@@ -25997,14 +25990,12 @@
                 "picocolors": {
                     "version": "1.0.0",
                     "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-                    "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
-                    "dev": true
+                    "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
                 },
                 "postcss": {
                     "version": "8.4.35",
                     "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
                     "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==",
-                    "dev": true,
                     "requires": {
                         "nanoid": "^3.3.7",
                         "picocolors": "^1.0.0",
@@ -26189,6 +26180,12 @@
             "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
             "dev": true
         },
+        "vuex": {
+            "version": "3.6.2",
+            "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz",
+            "integrity": "sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==",
+            "requires": {}
+        },
         "watchpack": {
             "version": "1.7.5",
             "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
diff --git a/courseware-block/package.json b/courseware-block/package.json
index b23034284107369270b54d37df2536eb34c96d08..7f4ac54a2f9ca24746569fe3349a0e098badcf5c 100644
--- a/courseware-block/package.json
+++ b/courseware-block/package.json
@@ -27,6 +27,7 @@
         "not IE <= 11"
     ],
     "dependencies": {
-        "axios": "^0.21.4"
+        "axios": "^0.21.4",
+        "vuex": "^3.6.2"
     }
 }