taleem-player 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +267 -0
- package/decks/angles_and_transversals.json +85 -0
- package/decks/congruent_triangles.json +169 -0
- package/decks/demo_deck.json +22 -0
- package/decks/eq_28aug2025.json +67 -0
- package/decks/goldstandar_eq_28aug25.json +67 -0
- package/decks/parallelogram_properties.json +164 -0
- package/decks/parallelogram_properties_no_sound.json +164 -0
- package/decks/posultate_and_SAS_postulate.json +76 -0
- package/decks/theorem_revision_ch10_11.fixed.json +265 -0
- package/decks/theorem_revision_ch10_11.json +269 -0
- package/decks/theorems9old_11.1.1.json +382 -0
- package/decks/theorems9old_11.1.2.json +162 -0
- package/decks/theorems9old_11.1.3.json +857 -0
- package/favicon.ico +0 -0
- package/package.json +17 -0
- package/src/Player.js +52 -0
- package/src/index.js +1 -0
- package/src/templates/barChart.js +14 -0
- package/src/templates/bulletList.js +10 -0
- package/src/templates/eq.js +26 -0
- package/src/templates/imageSlide.js +10 -0
- package/src/templates/index.js +16 -0
- package/src/templates/titleSlide.js +8 -0
- package/src/templates/twoColumnText.js +11 -0
- package/tests/fixtures/demoDeck.json +22 -0
- package/tests/player.basic.test.js +13 -0
- package/tests/player.eq.test.js +28 -0
package/favicon.ico
ADDED
|
File without changes
|
package/package.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "taleem-player",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"directories": {
|
|
7
|
+
"test": "tests"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "vitest"
|
|
11
|
+
},
|
|
12
|
+
"author": "",
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"vitest": "^4.0.16"
|
|
16
|
+
}
|
|
17
|
+
}
|
package/src/Player.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { slideTemplates } from "./templates/index.js";
|
|
2
|
+
|
|
3
|
+
export class Player {
|
|
4
|
+
constructor(deck) {
|
|
5
|
+
this.deck = deck;
|
|
6
|
+
this.slides = deck.deck;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// ===== OLD (kept for later timeline mode)
|
|
10
|
+
getSlideAt(time) {
|
|
11
|
+
return this.slides.find(
|
|
12
|
+
s => time >= s.start && time <= s.end
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
getFrame(time) {
|
|
17
|
+
const slide = this.getSlideAt(time);
|
|
18
|
+
if (!slide) return null;
|
|
19
|
+
|
|
20
|
+
return this._buildFrame(slide, time);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// ===== NEW (for manual navigation)
|
|
24
|
+
getFrameByIndex(index) {
|
|
25
|
+
const slide = this.slides[index];
|
|
26
|
+
if (!slide) return null;
|
|
27
|
+
|
|
28
|
+
// use slide.start to reveal everything
|
|
29
|
+
return this._buildFrame(slide, slide.end);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ===== shared internal logic
|
|
33
|
+
_buildFrame(slide, time) {
|
|
34
|
+
const template = slideTemplates[slide.type];
|
|
35
|
+
if (!template) {
|
|
36
|
+
throw new Error(`Unsupported slide type: ${slide.type}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const visibleData = slide.data.filter(
|
|
40
|
+
item => item.showAt === undefined || item.showAt <= time
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
type: slide.type,
|
|
45
|
+
regions: template.group(visibleData),
|
|
46
|
+
meta: {
|
|
47
|
+
start: slide.start,
|
|
48
|
+
end: slide.end
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Player } from "./Player.js";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
export const eq = {
|
|
3
|
+
group(data) {
|
|
4
|
+
const lines = [];
|
|
5
|
+
let current = null;
|
|
6
|
+
|
|
7
|
+
for (const item of data) {
|
|
8
|
+
if (!item.type.startsWith("sp")) {
|
|
9
|
+
current = {
|
|
10
|
+
type: item.type,
|
|
11
|
+
content: item.content,
|
|
12
|
+
spItems: []
|
|
13
|
+
};
|
|
14
|
+
lines.push(current);
|
|
15
|
+
} else if (current) {
|
|
16
|
+
current.spItems.push({
|
|
17
|
+
type: item.type,
|
|
18
|
+
content: item.content
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return { lines };
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
import { titleSlide } from "./titleSlide.js";
|
|
3
|
+
import { barChart } from "./barChart.js";
|
|
4
|
+
import { bulletList } from "./bulletList.js";
|
|
5
|
+
import { twoColumnText } from "./twoColumnText.js";
|
|
6
|
+
import { eq } from "./eq.js";
|
|
7
|
+
import { imageSlide } from "./imageSlide.js";
|
|
8
|
+
|
|
9
|
+
export const slideTemplates = {
|
|
10
|
+
titleSlide,
|
|
11
|
+
bulletList,
|
|
12
|
+
twoColumnText,
|
|
13
|
+
eq,
|
|
14
|
+
barChart,
|
|
15
|
+
imageSlide
|
|
16
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
export const twoColumnText = {
|
|
3
|
+
group(data) {
|
|
4
|
+
return {
|
|
5
|
+
title: data.find(d => d.name === "title")?.content ?? "",
|
|
6
|
+
left: data.filter(d => d.name === "left").map(d => d.content),
|
|
7
|
+
right: data.filter(d => d.name === "right").map(d => d.content)
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "deck-v1",
|
|
3
|
+
"name": "demo-minimal",
|
|
4
|
+
"deck": [
|
|
5
|
+
{
|
|
6
|
+
"start": 0,
|
|
7
|
+
"end": 10,
|
|
8
|
+
"type": "titleSlide",
|
|
9
|
+
"data": [
|
|
10
|
+
{ "name": "title", "content": "Angles and Transversals", "showAt": 0 }
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"start": 10,
|
|
15
|
+
"end": 20,
|
|
16
|
+
"type": "titleSlide",
|
|
17
|
+
"data": [
|
|
18
|
+
{ "name": "title", "content": "Parallel Lines and Transversals", "showAt": 0 }
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { Player } from "../src/Player.js";
|
|
3
|
+
import demoDeck from "./fixtures/demoDeck.json";
|
|
4
|
+
|
|
5
|
+
describe("Player basic behavior", () => {
|
|
6
|
+
it("renders first slide by index", () => {
|
|
7
|
+
const player = new Player(demoDeck);
|
|
8
|
+
const frame = player.getFrameByIndex(0);
|
|
9
|
+
|
|
10
|
+
expect(frame.type).toBe("titleSlide");
|
|
11
|
+
expect(frame.regions.title).toBe("Angles and Transversals");
|
|
12
|
+
});
|
|
13
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { Player } from "../src/Player.js";
|
|
3
|
+
|
|
4
|
+
const eqDeck = {
|
|
5
|
+
version: "deck-v1",
|
|
6
|
+
deck: [
|
|
7
|
+
{
|
|
8
|
+
start: 0,
|
|
9
|
+
end: 10,
|
|
10
|
+
type: "eq",
|
|
11
|
+
data: [
|
|
12
|
+
{ type: "math", content: "E = mc^2", showAt: 0 },
|
|
13
|
+
{ type: "spText", content: "Einstein" },
|
|
14
|
+
{ type: "text", content: "Final", showAt: 5 }
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
describe("EQ grouping", () => {
|
|
21
|
+
it("attaches spItems to previous line", () => {
|
|
22
|
+
const player = new Player(eqDeck);
|
|
23
|
+
const frame = player.getFrameByIndex(0);
|
|
24
|
+
|
|
25
|
+
expect(frame.regions.lines.length).toBe(2);
|
|
26
|
+
expect(frame.regions.lines[0].spItems.length).toBe(1);
|
|
27
|
+
});
|
|
28
|
+
});
|