diff --git a/ccna4-missing b/ccna4-missing
new file mode 100644
index 0000000..70ba21c
--- /dev/null
+++ b/ccna4-missing
@@ -0,0 +1,8 @@
+'21 | Next is not UL but: undefined',
+'52 | No correct answers found!',
+'98 | Next is not UL but: undefined',
+'99 | Next is not UL but: undefined',
+'100 | Next is not UL but: undefined',
+'143 | Next is not UL but: undefined',
+'144 | Next is not UL but: undefined',
+'145 | No correct answers found!'
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 8453f0a..409afc4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1038,6 +1038,12 @@
"physical-cpu-count": "^2.0.0"
}
},
+ "@types/elasticlunr": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@types/elasticlunr/-/elasticlunr-0.9.0.tgz",
+ "integrity": "sha512-7xUGaa0HqDmfawyFd8ANaoTHt5KF/BEdvKfqz4NxGEhbloIXGGtH065MOvC+YYQRZPAA/b5Vt/Xe5AmXoKTmhQ==",
+ "dev": true
+ },
"@types/navigo": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/@types/navigo/-/navigo-7.0.1.tgz",
@@ -2732,6 +2738,11 @@
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
"dev": true
},
+ "elasticlunr": {
+ "version": "0.9.5",
+ "resolved": "https://registry.npmjs.org/elasticlunr/-/elasticlunr-0.9.5.tgz",
+ "integrity": "sha1-ZVQbswnd3Qz5Ty0ciGGyvmUbsNU="
+ },
"electron-to-chromium": {
"version": "1.3.314",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.314.tgz",
diff --git a/package.json b/package.json
index a89f5de..36fdfcf 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,7 @@
"dependencies": {
"@hibas123/theme": "^1.2.14",
"@hibas123/utils": "^2.2.3",
+ "elasticlunr": "^0.9.5",
"feather-icons": "^4.24.1",
"navigo": "^7.1.2",
"svelte": "^3.16.0",
@@ -19,6 +20,7 @@
"uuid": "^3.3.3"
},
"devDependencies": {
+ "@types/elasticlunr": "^0.9.0",
"@types/navigo": "^7.0.1",
"@types/node": "^12.12.14",
"@types/uuid": "^3.4.6",
diff --git a/src/App.svelte b/src/App.svelte
index 418d25b..84ee45e 100644
--- a/src/App.svelte
+++ b/src/App.svelte
@@ -1,28 +1,40 @@
-
- {#if $DeviceType === DeviceTypes.MOBILE}
-
- {:else}
-
- {/if}
+
- {#if $ModalStore}
-
- {/if}
-
\ No newline at end of file
+
+
+ {#if $DeviceType === DeviceTypes.MOBILE}
+
+ {:else}
+
+ {/if}
+
+ {#if $ModalStore}
+
+ {/if}
+
+
+{version}
diff --git a/src/main.ts b/src/main.ts
index 0ab78d1..7bf02b1 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -43,4 +43,8 @@ const app = new App({
target: document.getElementById("content")
});
-export default app;
\ No newline at end of file
+export default app;
+
+if ('serviceWorker' in navigator) {
+ navigator.serviceWorker.register("sw.ts");
+}
\ No newline at end of file
diff --git a/src/router.ts b/src/router.ts
index 3c0f767..fb3abab 100644
--- a/src/router.ts
+++ b/src/router.ts
@@ -19,14 +19,28 @@ export const pageStore = readable(undefined, (set) => {
router.resolve();
});
+import Home from "./views/Home.svelte"
import Overview from "./views/Overview.svelte";
+import Browse from "./views/Browse.svelte";
router.on("/", (params) => {
+ setComponent({
+ desktop: Home as typeof SvelteComponent,
+ mobile: Home as typeof SvelteComponent,
+ params: {}
+ })
+}).on("/test", (params) => {
setComponent({
desktop: Overview as typeof SvelteComponent,
mobile: Overview as typeof SvelteComponent,
params
})
+}).on("/browse", (params) => {
+ setComponent({
+ desktop: Browse as typeof SvelteComponent,
+ mobile: Browse as typeof SvelteComponent,
+ params: {}
+ })
})
// .on("/:vaultid", (params) => {
diff --git a/src/stores.ts b/src/stores.ts
index c0bf807..7c36f5f 100644
--- a/src/stores.ts
+++ b/src/stores.ts
@@ -1,28 +1,35 @@
import { writable, readable } from "svelte/store";
-import { Question, Exam } from "./data";
+import { Question, Exam, QuestionTypes } from "./data";
import CCNA2 from "../ccna2.json";
import CCNA3 from "../ccna3.json";
import CCNA4 from "../ccna4.json";
import TestData from "../data-test.json";
-const tests = new Map();
-tests.set("ccna4", CCNA4);
-tests.set("ccna3", CCNA3);
-tests.set("ccna2", CCNA2);
-tests.set("test", TestData)
+const Tests = new Map();
+Tests.set("ccna4", CCNA4);
+Tests.set("ccna3", CCNA3);
+Tests.set("ccna2", CCNA2);
+Tests.set("test", TestData)
const DEFAULT = "ccna4";
-let test = new URL(window.location.href).searchParams.get("exam") || DEFAULT;
+export let test = new URL(window.location.href).searchParams.get("exam") || DEFAULT;
-const dataVersion = tests.has(test) ? test : DEFAULT;
-const Data = tests.get(dataVersion);
+const dataVersion = Tests.has(test) ? test : DEFAULT;
+const Data = Tests.get(dataVersion);
+const QuestionMap = new Map();
+
+Data.questions.forEach(q => QuestionMap.set(q.id, q));
console.log("Running exam:", dataVersion);
const runsShould = 3;
+import elasticlunr from "elasticlunr";
+
+console.log(elasticlunr);
+
class QuestionManager {
version: string = dataVersion;
@@ -40,6 +47,22 @@ class QuestionManager {
level: number
}[];
+ index: elasticlunr.Index<{ id: string, title: string, answers: string }>;
+
+ private getAnswerString(question: Question) {
+ switch (question.type) {
+ case QuestionTypes.SelectOne:
+ case QuestionTypes.SelectMultiple:
+ return Object.values(question.options).join(" ; ");
+ case QuestionTypes.TextInput:
+ return question.correct;
+ case QuestionTypes.AssignValues:
+ return [...Object.values(question.fields), ...Object.values(question.values)].join(" ; ");
+ default:
+ return "";
+ }
+ }
+
constructor() {
this.availableQuestions = Data.questions.map(question => {
return {
@@ -49,6 +72,32 @@ class QuestionManager {
})
this.getNewActive();
+
+ this.index = elasticlunr(function () {
+ this.addField("title")
+ this.addField("answers");
+ this.setRef("id")
+ })
+
+ Data.questions
+ .map(e => ({
+ id: e.id,
+ title: e.title,
+ answers: this.getAnswerString(e)
+ }))
+ .forEach(e => this.index.addDoc(e));
+ }
+
+ search(term: string) {
+ if (term === "")
+ return Data.questions;
+ const match = this.index.search(term, {
+ fields: {
+ title: { boost: 2 },
+ answers: { boost: 1 }
+ }
+ }).map(e => QuestionMap.get(e.ref));
+ return match;
}
getNewActive() {
@@ -108,4 +157,6 @@ export const IsDark = readable(Theme.isDark(), set => {
return () => Theme.isDarkObservable.unsubscribe(onChange);
})
-export { ModalStore } from "./modals";
\ No newline at end of file
+export { ModalStore } from "./modals";
+
+export const AvailableTests = Array.from(Tests.keys());
\ No newline at end of file
diff --git a/src/sw.ts b/src/sw.ts
new file mode 100644
index 0000000..08f4b40
--- /dev/null
+++ b/src/sw.ts
@@ -0,0 +1,37 @@
+var CACHE = 'cache-and-update';
+
+self.addEventListener('install', function (evt) {
+ console.log('The service worker is being installed.');
+ evt.waitUntil(precache());
+});
+
+self.addEventListener('fetch', function (evt: FetchEvent) {
+ console.log('The service worker is serving the asset.');
+ evt.respondWith(fromCache(evt.request, update(evt.request)));
+ evt.waitUntil(update(evt.request));
+});
+
+function precache() {
+ return caches.open(CACHE).then(function (cache) {
+ return cache.addAll([
+ "./",
+ "./index.html"
+ ]);
+ });
+}
+
+function fromCache(request, update) {
+ return caches.open(CACHE).then(function (cache) {
+ return cache.match(request).then(function (matching) {
+ return matching || update;
+ });
+ });
+}
+
+function update(request) {
+ return caches.open(CACHE).then(function (cache) {
+ return fetch(request).then(function (response) {
+ return cache.put(request, response);
+ });
+ });
+}
\ No newline at end of file
diff --git a/src/views/Browse.svelte b/src/views/Browse.svelte
new file mode 100644
index 0000000..309062b
--- /dev/null
+++ b/src/views/Browse.svelte
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/Home.svelte b/src/views/Home.svelte
new file mode 100644
index 0000000..ed5e8a4
--- /dev/null
+++ b/src/views/Home.svelte
@@ -0,0 +1,20 @@
+
+
+
+
Test your knowlegde
+
window.location.hash = "#/test"}>Test
+
Browse and search specific questions
+
window.location.hash = "#/browse"}>Search questions
+
+
+
+ {#each AvailableTests as test}
+ {test}
+ {/each}
+
+
window.location.href = "./?exam=" + selected}>switch
+
\ No newline at end of file
diff --git a/src/views/Overview.svelte b/src/views/Overview.svelte
index 674b978..e6ec696 100644
--- a/src/views/Overview.svelte
+++ b/src/views/Overview.svelte
@@ -1,8 +1,7 @@