waitroom 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 +62 -0
- package/dist/chunk-3RJ542WD.js +130 -0
- package/dist/chunk-3RJ542WD.js.map +1 -0
- package/dist/chunk-4DE2IREA.cjs +9 -0
- package/dist/chunk-4DE2IREA.cjs.map +1 -0
- package/dist/chunk-5AUPIR2C.cjs +90 -0
- package/dist/chunk-5AUPIR2C.cjs.map +1 -0
- package/dist/chunk-ARXVTVP4.js +55 -0
- package/dist/chunk-ARXVTVP4.js.map +1 -0
- package/dist/chunk-C5XPYOJI.js +137 -0
- package/dist/chunk-C5XPYOJI.js.map +1 -0
- package/dist/chunk-DEQZY4AM.js +58 -0
- package/dist/chunk-DEQZY4AM.js.map +1 -0
- package/dist/chunk-FH3QBC6T.cjs +139 -0
- package/dist/chunk-FH3QBC6T.cjs.map +1 -0
- package/dist/chunk-GEBKOXLQ.cjs +255 -0
- package/dist/chunk-GEBKOXLQ.cjs.map +1 -0
- package/dist/chunk-JG5ZMB2Y.cjs +142 -0
- package/dist/chunk-JG5ZMB2Y.cjs.map +1 -0
- package/dist/chunk-MAWVAR3Q.cjs +135 -0
- package/dist/chunk-MAWVAR3Q.cjs.map +1 -0
- package/dist/chunk-MMNQMDV3.js +39 -0
- package/dist/chunk-MMNQMDV3.js.map +1 -0
- package/dist/chunk-O6CAFCTV.js +140 -0
- package/dist/chunk-O6CAFCTV.js.map +1 -0
- package/dist/chunk-P6NO27XB.cjs +74 -0
- package/dist/chunk-P6NO27XB.cjs.map +1 -0
- package/dist/chunk-PKRYY3X6.cjs +60 -0
- package/dist/chunk-PKRYY3X6.cjs.map +1 -0
- package/dist/chunk-PUR7CO53.js +72 -0
- package/dist/chunk-PUR7CO53.js.map +1 -0
- package/dist/chunk-R5V2UBE7.js +88 -0
- package/dist/chunk-R5V2UBE7.js.map +1 -0
- package/dist/chunk-SSP4S4NY.cjs +57 -0
- package/dist/chunk-SSP4S4NY.cjs.map +1 -0
- package/dist/chunk-SUJCEDVR.js +251 -0
- package/dist/chunk-SUJCEDVR.js.map +1 -0
- package/dist/chunk-V4RO47V6.cjs +41 -0
- package/dist/chunk-V4RO47V6.cjs.map +1 -0
- package/dist/chunk-V5DABI44.cjs +172 -0
- package/dist/chunk-V5DABI44.cjs.map +1 -0
- package/dist/chunk-V6TY7KAL.js +7 -0
- package/dist/chunk-V6TY7KAL.js.map +1 -0
- package/dist/chunk-VKSLYTRF.js +170 -0
- package/dist/chunk-VKSLYTRF.js.map +1 -0
- package/dist/core/index.cjs +30 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +23 -0
- package/dist/core/index.d.ts +23 -0
- package/dist/core/index.js +5 -0
- package/dist/core/index.js.map +1 -0
- package/dist/doodle/basic-canvas.cjs +13 -0
- package/dist/doodle/basic-canvas.cjs.map +1 -0
- package/dist/doodle/basic-canvas.d.cts +5 -0
- package/dist/doodle/basic-canvas.d.ts +5 -0
- package/dist/doodle/basic-canvas.js +4 -0
- package/dist/doodle/basic-canvas.js.map +1 -0
- package/dist/doodle/index.cjs +13 -0
- package/dist/doodle/index.cjs.map +1 -0
- package/dist/doodle/index.d.cts +2 -0
- package/dist/doodle/index.d.ts +2 -0
- package/dist/doodle/index.js +4 -0
- package/dist/doodle/index.js.map +1 -0
- package/dist/engine--hGQ4LNR.d.ts +16 -0
- package/dist/engine-DdHCpfbk.d.cts +16 -0
- package/dist/facts/dev-tips.cjs +13 -0
- package/dist/facts/dev-tips.cjs.map +1 -0
- package/dist/facts/dev-tips.d.cts +5 -0
- package/dist/facts/dev-tips.d.ts +5 -0
- package/dist/facts/dev-tips.js +4 -0
- package/dist/facts/dev-tips.js.map +1 -0
- package/dist/facts/index.cjs +23 -0
- package/dist/facts/index.cjs.map +1 -0
- package/dist/facts/index.d.cts +4 -0
- package/dist/facts/index.d.ts +4 -0
- package/dist/facts/index.js +6 -0
- package/dist/facts/index.js.map +1 -0
- package/dist/facts/programming-trivia.cjs +13 -0
- package/dist/facts/programming-trivia.cjs.map +1 -0
- package/dist/facts/programming-trivia.d.cts +5 -0
- package/dist/facts/programming-trivia.d.ts +5 -0
- package/dist/facts/programming-trivia.js +4 -0
- package/dist/facts/programming-trivia.js.map +1 -0
- package/dist/facts/tech-stats.cjs +13 -0
- package/dist/facts/tech-stats.cjs.map +1 -0
- package/dist/facts/tech-stats.d.cts +5 -0
- package/dist/facts/tech-stats.d.ts +5 -0
- package/dist/facts/tech-stats.js +4 -0
- package/dist/facts/tech-stats.js.map +1 -0
- package/dist/games/click-counter.cjs +13 -0
- package/dist/games/click-counter.cjs.map +1 -0
- package/dist/games/click-counter.d.cts +5 -0
- package/dist/games/click-counter.d.ts +5 -0
- package/dist/games/click-counter.js +4 -0
- package/dist/games/click-counter.js.map +1 -0
- package/dist/games/index.cjs +23 -0
- package/dist/games/index.cjs.map +1 -0
- package/dist/games/index.d.cts +4 -0
- package/dist/games/index.d.ts +4 -0
- package/dist/games/index.js +6 -0
- package/dist/games/index.js.map +1 -0
- package/dist/games/memory.cjs +13 -0
- package/dist/games/memory.cjs.map +1 -0
- package/dist/games/memory.d.cts +5 -0
- package/dist/games/memory.d.ts +5 -0
- package/dist/games/memory.js +4 -0
- package/dist/games/memory.js.map +1 -0
- package/dist/games/snake.cjs +13 -0
- package/dist/games/snake.cjs.map +1 -0
- package/dist/games/snake.d.cts +5 -0
- package/dist/games/snake.d.ts +5 -0
- package/dist/games/snake.js +4 -0
- package/dist/games/snake.js.map +1 -0
- package/dist/index.cjs +43 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/react/index.cjs +22 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +24 -0
- package/dist/react/index.d.ts +24 -0
- package/dist/react/index.js +5 -0
- package/dist/react/index.js.map +1 -0
- package/dist/types-vBwPFyxq.d.cts +101 -0
- package/dist/types-vBwPFyxq.d.ts +101 -0
- package/package.json +64 -0
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# waitroom
|
|
2
|
+
|
|
3
|
+
Transform dead loading time into engaging micro-interactions.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install waitroom
|
|
9
|
+
# or
|
|
10
|
+
yarn add waitroom
|
|
11
|
+
# or
|
|
12
|
+
pnpm add waitroom
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start (React)
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { useState } from 'react';
|
|
19
|
+
import { LoadingInteraction } from 'waitroom';
|
|
20
|
+
import { SnakeGame } from 'waitroom/games/snake';
|
|
21
|
+
import { DevTipsFacts } from 'waitroom/facts/dev-tips';
|
|
22
|
+
|
|
23
|
+
function App() {
|
|
24
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<LoadingInteraction
|
|
28
|
+
isLoading={isLoading}
|
|
29
|
+
availableModes={['game', 'facts']}
|
|
30
|
+
game={SnakeGame}
|
|
31
|
+
facts={DevTipsFacts}
|
|
32
|
+
>
|
|
33
|
+
<YourContent />
|
|
34
|
+
</LoadingInteraction>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Examples
|
|
40
|
+
|
|
41
|
+
### React Demo
|
|
42
|
+
A comprehensive React example is available in `examples/react-demo`.
|
|
43
|
+
|
|
44
|
+
To run it:
|
|
45
|
+
1. `npm run build` (in root)
|
|
46
|
+
2. `cd examples/react-demo`
|
|
47
|
+
3. `npm install`
|
|
48
|
+
4. `npm run dev`
|
|
49
|
+
|
|
50
|
+
This demo showcases:
|
|
51
|
+
- All interaction modes (Game, Facts, Doodle)
|
|
52
|
+
- Mode switching
|
|
53
|
+
- Custom themes
|
|
54
|
+
- Full-screen expansion capability
|
|
55
|
+
|
|
56
|
+
## Architecture
|
|
57
|
+
The package is designed for tree-shaking:
|
|
58
|
+
- `waitroom/core`: Framework-agnostic engine
|
|
59
|
+
- `waitroom/games/*`: Individual games
|
|
60
|
+
- `waitroom/facts/*`: Individual fact collections
|
|
61
|
+
- `waitroom/doodle/*`: Doodle plugins
|
|
62
|
+
- `waitroom/react`: React components only
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { __publicField } from './chunk-V6TY7KAL.js';
|
|
2
|
+
|
|
3
|
+
// src/core/state.ts
|
|
4
|
+
var STORAGE_KEY_PREFIX = "waitroom_";
|
|
5
|
+
var _StateManager = class _StateManager {
|
|
6
|
+
constructor() {
|
|
7
|
+
}
|
|
8
|
+
static getInstance() {
|
|
9
|
+
if (!_StateManager.instance) {
|
|
10
|
+
_StateManager.instance = new _StateManager();
|
|
11
|
+
}
|
|
12
|
+
return _StateManager.instance;
|
|
13
|
+
}
|
|
14
|
+
// --- Game State ---
|
|
15
|
+
getGameState(gameId) {
|
|
16
|
+
try {
|
|
17
|
+
const data = localStorage.getItem(`${STORAGE_KEY_PREFIX}game_${gameId}`);
|
|
18
|
+
if (data) {
|
|
19
|
+
return JSON.parse(data);
|
|
20
|
+
}
|
|
21
|
+
} catch (e) {
|
|
22
|
+
console.warn("Failed to load game state", e);
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
saveGameState(gameId, state) {
|
|
27
|
+
try {
|
|
28
|
+
localStorage.setItem(
|
|
29
|
+
`${STORAGE_KEY_PREFIX}game_${gameId}`,
|
|
30
|
+
JSON.stringify(state)
|
|
31
|
+
);
|
|
32
|
+
} catch (e) {
|
|
33
|
+
console.warn("Failed to save game state", e);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// --- Mode Preference ---
|
|
37
|
+
getPreferredMode() {
|
|
38
|
+
try {
|
|
39
|
+
return localStorage.getItem(
|
|
40
|
+
`${STORAGE_KEY_PREFIX}mode`
|
|
41
|
+
);
|
|
42
|
+
} catch (e) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
savePreferredMode(mode) {
|
|
47
|
+
try {
|
|
48
|
+
localStorage.setItem(`${STORAGE_KEY_PREFIX}mode`, mode);
|
|
49
|
+
} catch (e) {
|
|
50
|
+
console.warn("Failed to save preferred mode", e);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
__publicField(_StateManager, "instance");
|
|
55
|
+
var StateManager = _StateManager;
|
|
56
|
+
var stateManager = StateManager.getInstance();
|
|
57
|
+
|
|
58
|
+
// src/core/engine.ts
|
|
59
|
+
var LoadingEngine = class {
|
|
60
|
+
constructor(container, config) {
|
|
61
|
+
__publicField(this, "config");
|
|
62
|
+
__publicField(this, "container");
|
|
63
|
+
__publicField(this, "currentInstance", null);
|
|
64
|
+
__publicField(this, "activeMode", "none");
|
|
65
|
+
this.container = container;
|
|
66
|
+
this.config = config;
|
|
67
|
+
}
|
|
68
|
+
init() {
|
|
69
|
+
let startMode = this.config.mode || "none";
|
|
70
|
+
if (this.config.persistModePreference) {
|
|
71
|
+
const saved = stateManager.getPreferredMode();
|
|
72
|
+
if (saved && this.config.availableModes?.includes(saved)) {
|
|
73
|
+
startMode = saved;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
this.setMode(startMode);
|
|
77
|
+
}
|
|
78
|
+
setMode(mode) {
|
|
79
|
+
if (this.activeMode === mode) return;
|
|
80
|
+
if (this.currentInstance) {
|
|
81
|
+
this.currentInstance.destroy();
|
|
82
|
+
this.currentInstance = null;
|
|
83
|
+
}
|
|
84
|
+
this.activeMode = mode;
|
|
85
|
+
this.container.style.opacity = "0";
|
|
86
|
+
this.container.style.transition = `opacity ${this.config.transitionDuration || 300}ms ease-in-out`;
|
|
87
|
+
setTimeout(() => {
|
|
88
|
+
this.render();
|
|
89
|
+
this.container.style.opacity = "1";
|
|
90
|
+
}, (this.config.transitionDuration || 300) / 2);
|
|
91
|
+
if (this.config.persistModePreference && mode !== "none") {
|
|
92
|
+
stateManager.savePreferredMode(mode);
|
|
93
|
+
}
|
|
94
|
+
if (this.config.onModeChange) {
|
|
95
|
+
this.config.onModeChange(mode);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
render() {
|
|
99
|
+
this.container.innerHTML = "";
|
|
100
|
+
if (this.activeMode === "none") {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (this.activeMode === "game" && this.config.game) {
|
|
104
|
+
const gamePlugin = this.config.game;
|
|
105
|
+
const savedState = stateManager.getGameState(gamePlugin.id) || {};
|
|
106
|
+
this.currentInstance = gamePlugin.renderMini(this.container, savedState);
|
|
107
|
+
} else if (this.activeMode === "facts" && this.config.facts) {
|
|
108
|
+
const factsPlugin = this.config.facts;
|
|
109
|
+
this.currentInstance = factsPlugin.renderMini(this.container);
|
|
110
|
+
} else if (this.activeMode === "doodle" && this.config.doodle) {
|
|
111
|
+
const doodlePlugin = this.config.doodle;
|
|
112
|
+
this.currentInstance = doodlePlugin.renderMini(this.container);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
destroy() {
|
|
116
|
+
if (this.currentInstance) {
|
|
117
|
+
this.currentInstance.destroy();
|
|
118
|
+
}
|
|
119
|
+
this.container.innerHTML = "";
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
function createLoadingInteraction(container, config) {
|
|
123
|
+
const engine = new LoadingEngine(container, config);
|
|
124
|
+
engine.init();
|
|
125
|
+
return engine;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export { LoadingEngine, StateManager, createLoadingInteraction, stateManager };
|
|
129
|
+
//# sourceMappingURL=chunk-3RJ542WD.js.map
|
|
130
|
+
//# sourceMappingURL=chunk-3RJ542WD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/state.ts","../src/core/engine.ts"],"names":[],"mappings":"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","file":"chunk-3RJ542WD.js","sourcesContent":["import { GameState, InteractionMode } from \"./types\";\n\nconst STORAGE_KEY_PREFIX = \"waitroom_\";\n\nexport class StateManager {\n private static instance: StateManager;\n\n private constructor() {}\n\n static getInstance(): StateManager {\n if (!StateManager.instance) {\n StateManager.instance = new StateManager();\n }\n return StateManager.instance;\n }\n\n // --- Game State ---\n\n getGameState(gameId: string): Partial<GameState> | null {\n try {\n const data = localStorage.getItem(`${STORAGE_KEY_PREFIX}game_${gameId}`);\n if (data) {\n return JSON.parse(data);\n }\n } catch (e) {\n console.warn(\"Failed to load game state\", e);\n }\n return null;\n }\n\n saveGameState(gameId: string, state: Partial<GameState>): void {\n try {\n // Simple debounce could be added here if needed, but for now direct write\n localStorage.setItem(\n `${STORAGE_KEY_PREFIX}game_${gameId}`,\n JSON.stringify(state)\n );\n } catch (e) {\n console.warn(\"Failed to save game state\", e);\n }\n }\n\n // --- Mode Preference ---\n\n getPreferredMode(): InteractionMode | null {\n try {\n return localStorage.getItem(\n `${STORAGE_KEY_PREFIX}mode`\n ) as InteractionMode;\n } catch (e) {\n return null;\n }\n }\n\n savePreferredMode(mode: InteractionMode): void {\n try {\n localStorage.setItem(`${STORAGE_KEY_PREFIX}mode`, mode);\n } catch (e) {\n console.warn(\"Failed to save preferred mode\", e);\n }\n }\n}\n\nexport const stateManager = StateManager.getInstance();\n","import { InteractionConfig, InteractionMode } from \"./types\";\nimport { stateManager } from \"./state\";\n\nexport class LoadingEngine {\n private config: InteractionConfig;\n private container: HTMLElement;\n private currentInstance: any = null;\n private activeMode: InteractionMode = \"none\";\n\n constructor(container: HTMLElement, config: InteractionConfig) {\n this.container = container;\n this.config = config;\n }\n\n init() {\n // Determine start mode\n let startMode = this.config.mode || \"none\";\n\n if (this.config.persistModePreference) {\n const saved = stateManager.getPreferredMode();\n if (saved && this.config.availableModes?.includes(saved)) {\n startMode = saved;\n }\n }\n\n this.setMode(startMode);\n }\n\n setMode(mode: InteractionMode) {\n if (this.activeMode === mode) return;\n\n // Cleanup previous\n if (this.currentInstance) {\n this.currentInstance.destroy();\n this.currentInstance = null;\n }\n\n this.activeMode = mode;\n\n // Simple fade transition\n this.container.style.opacity = \"0\";\n this.container.style.transition = `opacity ${\n this.config.transitionDuration || 300\n }ms ease-in-out`;\n\n setTimeout(() => {\n this.render();\n this.container.style.opacity = \"1\";\n }, (this.config.transitionDuration || 300) / 2);\n\n // Persist preference\n if (this.config.persistModePreference && mode !== \"none\") {\n stateManager.savePreferredMode(mode);\n }\n\n if (this.config.onModeChange) {\n this.config.onModeChange(mode);\n }\n }\n\n private render() {\n this.container.innerHTML = \"\"; // Clear container\n\n if (this.activeMode === \"none\") {\n return;\n }\n\n // Normally we would have a plugin registry or pass plugins in config.\n // For this lightweight version we rely on config having the specific plugin instances.\n\n // Render based on mode\n if (this.activeMode === \"game\" && this.config.game) {\n const gamePlugin = this.config.game;\n // Load state\n const savedState = stateManager.getGameState(gamePlugin.id) || {};\n this.currentInstance = gamePlugin.renderMini(this.container, savedState);\n } else if (this.activeMode === \"facts\" && this.config.facts) {\n const factsPlugin = this.config.facts;\n this.currentInstance = factsPlugin.renderMini(this.container);\n } else if (this.activeMode === \"doodle\" && this.config.doodle) {\n const doodlePlugin = this.config.doodle;\n this.currentInstance = doodlePlugin.renderMini(this.container);\n }\n }\n\n destroy() {\n if (this.currentInstance) {\n this.currentInstance.destroy();\n }\n this.container.innerHTML = \"\";\n }\n}\n\nexport function createLoadingInteraction(\n container: HTMLElement,\n config: InteractionConfig\n) {\n const engine = new LoadingEngine(container, config);\n engine.init();\n return engine;\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
6
|
+
|
|
7
|
+
exports.__publicField = __publicField;
|
|
8
|
+
//# sourceMappingURL=chunk-4DE2IREA.cjs.map
|
|
9
|
+
//# sourceMappingURL=chunk-4DE2IREA.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-4DE2IREA.cjs"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk4DE2IREA_cjs = require('./chunk-4DE2IREA.cjs');
|
|
4
|
+
|
|
5
|
+
// src/facts/dev-tips.ts
|
|
6
|
+
var TIPS = [
|
|
7
|
+
{
|
|
8
|
+
id: "1",
|
|
9
|
+
text: "Ctrl+Shift+P opens command palette in VS Code",
|
|
10
|
+
category: "vscode"
|
|
11
|
+
},
|
|
12
|
+
{ id: "2", text: "Use git reflog to find lost commits", category: "git" },
|
|
13
|
+
{
|
|
14
|
+
id: "3",
|
|
15
|
+
text: "Console.table() displays data in a table format",
|
|
16
|
+
category: "js"
|
|
17
|
+
},
|
|
18
|
+
{ id: "4", text: "Alt+Click to use multiple cursors", category: "vscode" }
|
|
19
|
+
];
|
|
20
|
+
var SimpleFactsRenderer = class {
|
|
21
|
+
constructor(container, facts, config) {
|
|
22
|
+
chunk4DE2IREA_cjs.__publicField(this, "container");
|
|
23
|
+
chunk4DE2IREA_cjs.__publicField(this, "facts");
|
|
24
|
+
chunk4DE2IREA_cjs.__publicField(this, "currentIndex", 0);
|
|
25
|
+
chunk4DE2IREA_cjs.__publicField(this, "timer");
|
|
26
|
+
chunk4DE2IREA_cjs.__publicField(this, "config");
|
|
27
|
+
this.container = container;
|
|
28
|
+
this.facts = facts;
|
|
29
|
+
this.config = config || {};
|
|
30
|
+
this.container.style.display = "flex";
|
|
31
|
+
this.container.style.flexDirection = "column";
|
|
32
|
+
this.container.style.alignItems = "center";
|
|
33
|
+
this.container.style.justifyContent = "center";
|
|
34
|
+
this.container.style.padding = "20px";
|
|
35
|
+
this.container.style.textAlign = "center";
|
|
36
|
+
this.showCurrent();
|
|
37
|
+
this.startRotation();
|
|
38
|
+
}
|
|
39
|
+
showCurrent() {
|
|
40
|
+
const fact = this.facts[this.currentIndex];
|
|
41
|
+
this.container.innerHTML = `
|
|
42
|
+
<div style="font-weight: bold; margin-bottom: 8px;">Tip #${this.currentIndex + 1}</div>
|
|
43
|
+
<div style="font-size: 1.1em;">${fact.text}</div>
|
|
44
|
+
${fact.category ? `<div style="font-size: 0.8em; color: #888; margin-top: 5px;">${fact.category}</div>` : ""}
|
|
45
|
+
`;
|
|
46
|
+
const timerBar = document.createElement("div");
|
|
47
|
+
timerBar.style.width = "0%";
|
|
48
|
+
timerBar.style.height = "2px";
|
|
49
|
+
timerBar.style.background = "#22c55e";
|
|
50
|
+
timerBar.style.marginTop = "10px";
|
|
51
|
+
timerBar.style.transition = `width ${this.config.rotationInterval || 4e3}ms linear`;
|
|
52
|
+
void this.container.offsetWidth;
|
|
53
|
+
this.container.appendChild(timerBar);
|
|
54
|
+
requestAnimationFrame(() => {
|
|
55
|
+
timerBar.style.width = "100%";
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
startRotation() {
|
|
59
|
+
if (this.timer) clearInterval(this.timer);
|
|
60
|
+
const interval = this.config.rotationInterval || 4e3;
|
|
61
|
+
this.timer = setInterval(() => this.next(), interval);
|
|
62
|
+
}
|
|
63
|
+
next() {
|
|
64
|
+
this.currentIndex = (this.currentIndex + 1) % this.facts.length;
|
|
65
|
+
this.showCurrent();
|
|
66
|
+
}
|
|
67
|
+
previous() {
|
|
68
|
+
this.currentIndex = (this.currentIndex - 1 + this.facts.length) % this.facts.length;
|
|
69
|
+
this.showCurrent();
|
|
70
|
+
}
|
|
71
|
+
favorite(id) {
|
|
72
|
+
console.log("Fav:", id);
|
|
73
|
+
}
|
|
74
|
+
destroy() {
|
|
75
|
+
if (this.timer) clearInterval(this.timer);
|
|
76
|
+
this.container.innerHTML = "";
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
var DevTipsFacts = {
|
|
80
|
+
id: "dev-tips",
|
|
81
|
+
name: "Developer Tips",
|
|
82
|
+
category: "coding",
|
|
83
|
+
facts: TIPS,
|
|
84
|
+
renderMini: (c, cfg) => new SimpleFactsRenderer(c, TIPS, cfg),
|
|
85
|
+
renderFull: (c, cfg) => new SimpleFactsRenderer(c, TIPS, cfg)
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
exports.DevTipsFacts = DevTipsFacts;
|
|
89
|
+
//# sourceMappingURL=chunk-5AUPIR2C.cjs.map
|
|
90
|
+
//# sourceMappingURL=chunk-5AUPIR2C.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/facts/dev-tips.ts"],"names":["__publicField"],"mappings":";;;;;AAEA,IAAM,IAAA,GAAe;AAAA,EACnB;AAAA,IACE,EAAA,EAAI,GAAA;AAAA,IACJ,IAAA,EAAM,+CAAA;AAAA,IACN,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,EAAE,EAAA,EAAI,GAAA,EAAK,IAAA,EAAM,qCAAA,EAAuC,UAAU,KAAA,EAAM;AAAA,EACxE;AAAA,IACE,EAAA,EAAI,GAAA;AAAA,IACJ,IAAA,EAAM,iDAAA;AAAA,IACN,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,EAAE,EAAA,EAAI,GAAA,EAAK,IAAA,EAAM,mCAAA,EAAqC,UAAU,QAAA;AAClE,CAAA;AAEA,IAAM,sBAAN,MAAmD;AAAA,EAOjD,WAAA,CAAY,SAAA,EAAwB,KAAA,EAAe,MAAA,EAAsB;AANzE,IAAAA,+BAAA,CAAA,IAAA,EAAQ,WAAA,CAAA;AACR,IAAAA,+BAAA,CAAA,IAAA,EAAQ,OAAA,CAAA;AACR,IAAAA,+BAAA,CAAA,IAAA,EAAQ,cAAA,EAAe,CAAA,CAAA;AACvB,IAAAA,+BAAA,CAAA,IAAA,EAAQ,OAAA,CAAA;AACR,IAAAA,+BAAA,CAAA,IAAA,EAAQ,QAAA,CAAA;AAGN,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,IAAA,CAAK,MAAA,GAAS,UAAU,EAAC;AAEzB,IAAA,IAAA,CAAK,SAAA,CAAU,MAAM,OAAA,GAAU,MAAA;AAC/B,IAAA,IAAA,CAAK,SAAA,CAAU,MAAM,aAAA,GAAgB,QAAA;AACrC,IAAA,IAAA,CAAK,SAAA,CAAU,MAAM,UAAA,GAAa,QAAA;AAClC,IAAA,IAAA,CAAK,SAAA,CAAU,MAAM,cAAA,GAAiB,QAAA;AACtC,IAAA,IAAA,CAAK,SAAA,CAAU,MAAM,OAAA,GAAU,MAAA;AAC/B,IAAA,IAAA,CAAK,SAAA,CAAU,MAAM,SAAA,GAAY,QAAA;AAEjC,IAAA,IAAA,CAAK,WAAA,EAAY;AACjB,IAAA,IAAA,CAAK,aAAA,EAAc;AAAA,EACrB;AAAA,EAEQ,WAAA,GAAc;AACpB,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,YAAY,CAAA;AACzC,IAAA,IAAA,CAAK,UAAU,SAAA,GAAY;AAAA,qEAAA,EAEjB,IAAA,CAAK,eAAe,CACtB,CAAA;AAAA,2CAAA,EACiC,KAAK,IAAI,CAAA;AAAA,YAAA,EAExC,KAAK,QAAA,GACD,CAAA,6DAAA,EAAgE,IAAA,CAAK,QAAQ,WAC7E,EACN;AAAA,QAAA,CAAA;AAIR,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AAC7C,IAAA,QAAA,CAAS,MAAM,KAAA,GAAQ,IAAA;AACvB,IAAA,QAAA,CAAS,MAAM,MAAA,GAAS,KAAA;AACxB,IAAA,QAAA,CAAS,MAAM,UAAA,GAAa,SAAA;AAC5B,IAAA,QAAA,CAAS,MAAM,SAAA,GAAY,MAAA;AAC3B,IAAA,QAAA,CAAS,MAAM,UAAA,GAAa,CAAA,MAAA,EAC1B,IAAA,CAAK,MAAA,CAAO,oBAAoB,GAClC,CAAA,SAAA,CAAA;AAIA,IAAA,KAAK,KAAK,SAAA,CAAU,WAAA;AAEpB,IAAA,IAAA,CAAK,SAAA,CAAU,YAAY,QAAQ,CAAA;AAGnC,IAAA,qBAAA,CAAsB,MAAM;AAC1B,MAAA,QAAA,CAAS,MAAM,KAAA,GAAQ,MAAA;AAAA,IACzB,CAAC,CAAA;AAAA,EACH;AAAA,EAEQ,aAAA,GAAgB;AACtB,IAAA,IAAI,IAAA,CAAK,KAAA,EAAO,aAAA,CAAc,IAAA,CAAK,KAAK,CAAA;AACxC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,gBAAA,IAAoB,GAAA;AACjD,IAAA,IAAA,CAAK,QAAQ,WAAA,CAAY,MAAM,IAAA,CAAK,IAAA,IAAQ,QAAQ,CAAA;AAAA,EACtD;AAAA,EAEA,IAAA,GAAO;AACL,IAAA,IAAA,CAAK,YAAA,GAAA,CAAgB,IAAA,CAAK,YAAA,GAAe,CAAA,IAAK,KAAK,KAAA,CAAM,MAAA;AACzD,IAAA,IAAA,CAAK,WAAA,EAAY;AAAA,EACnB;AAAA,EAEA,QAAA,GAAW;AACT,IAAA,IAAA,CAAK,YAAA,GAAA,CACF,KAAK,YAAA,GAAe,CAAA,GAAI,KAAK,KAAA,CAAM,MAAA,IAAU,KAAK,KAAA,CAAM,MAAA;AAC3D,IAAA,IAAA,CAAK,WAAA,EAAY;AAAA,EACnB;AAAA,EAEA,SAAS,EAAA,EAAY;AACnB,IAAA,OAAA,CAAQ,GAAA,CAAI,QAAQ,EAAE,CAAA;AAAA,EACxB;AAAA,EAEA,OAAA,GAAU;AACR,IAAA,IAAI,IAAA,CAAK,KAAA,EAAO,aAAA,CAAc,IAAA,CAAK,KAAK,CAAA;AACxC,IAAA,IAAA,CAAK,UAAU,SAAA,GAAY,EAAA;AAAA,EAC7B;AACF,CAAA;AAEO,IAAM,YAAA,GAA4B;AAAA,EACvC,EAAA,EAAI,UAAA;AAAA,EACJ,IAAA,EAAM,gBAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,KAAA,EAAO,IAAA;AAAA,EACP,UAAA,EAAY,CAAC,CAAA,EAAG,GAAA,KAAQ,IAAI,mBAAA,CAAoB,CAAA,EAAG,MAAM,GAAG,CAAA;AAAA,EAC5D,UAAA,EAAY,CAAC,CAAA,EAAG,GAAA,KAAQ,IAAI,mBAAA,CAAoB,CAAA,EAAG,MAAM,GAAG;AAC9D","file":"chunk-5AUPIR2C.cjs","sourcesContent":["import { FactsPlugin, FactsInstance, Fact, FactsConfig } from \"../core/types\";\n\nconst TIPS: Fact[] = [\n {\n id: \"1\",\n text: \"Ctrl+Shift+P opens command palette in VS Code\",\n category: \"vscode\",\n },\n { id: \"2\", text: \"Use git reflog to find lost commits\", category: \"git\" },\n {\n id: \"3\",\n text: \"Console.table() displays data in a table format\",\n category: \"js\",\n },\n { id: \"4\", text: \"Alt+Click to use multiple cursors\", category: \"vscode\" },\n];\n\nclass SimpleFactsRenderer implements FactsInstance {\n private container: HTMLElement;\n private facts: Fact[];\n private currentIndex = 0;\n private timer: any;\n private config: FactsConfig;\n\n constructor(container: HTMLElement, facts: Fact[], config?: FactsConfig) {\n this.container = container;\n this.facts = facts;\n this.config = config || {};\n\n this.container.style.display = \"flex\";\n this.container.style.flexDirection = \"column\";\n this.container.style.alignItems = \"center\";\n this.container.style.justifyContent = \"center\";\n this.container.style.padding = \"20px\";\n this.container.style.textAlign = \"center\";\n\n this.showCurrent();\n this.startRotation();\n }\n\n private showCurrent() {\n const fact = this.facts[this.currentIndex];\n this.container.innerHTML = `\n <div style=\"font-weight: bold; margin-bottom: 8px;\">Tip #${\n this.currentIndex + 1\n }</div>\n <div style=\"font-size: 1.1em;\">${fact.text}</div>\n ${\n fact.category\n ? `<div style=\"font-size: 0.8em; color: #888; margin-top: 5px;\">${fact.category}</div>`\n : \"\"\n }\n `;\n\n // Add timer bar\n const timerBar = document.createElement(\"div\");\n timerBar.style.width = \"0%\";\n timerBar.style.height = \"2px\";\n timerBar.style.background = \"#22c55e\"; // Green progress\n timerBar.style.marginTop = \"10px\";\n timerBar.style.transition = `width ${\n this.config.rotationInterval || 4000\n }ms linear`;\n\n // Reset animation\n // Force reflow\n void this.container.offsetWidth;\n\n this.container.appendChild(timerBar);\n\n // Trigger animation\n requestAnimationFrame(() => {\n timerBar.style.width = \"100%\";\n });\n }\n\n private startRotation() {\n if (this.timer) clearInterval(this.timer);\n const interval = this.config.rotationInterval || 4000;\n this.timer = setInterval(() => this.next(), interval);\n }\n\n next() {\n this.currentIndex = (this.currentIndex + 1) % this.facts.length;\n this.showCurrent();\n }\n\n previous() {\n this.currentIndex =\n (this.currentIndex - 1 + this.facts.length) % this.facts.length;\n this.showCurrent();\n }\n\n favorite(id: string) {\n console.log(\"Fav:\", id);\n }\n\n destroy() {\n if (this.timer) clearInterval(this.timer);\n this.container.innerHTML = \"\";\n }\n}\n\nexport const DevTipsFacts: FactsPlugin = {\n id: \"dev-tips\",\n name: \"Developer Tips\",\n category: \"coding\",\n facts: TIPS,\n renderMini: (c, cfg) => new SimpleFactsRenderer(c, TIPS, cfg),\n renderFull: (c, cfg) => new SimpleFactsRenderer(c, TIPS, cfg),\n};\n"]}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { __publicField } from './chunk-V6TY7KAL.js';
|
|
2
|
+
|
|
3
|
+
// src/core/portal.ts
|
|
4
|
+
var PortalSystem = class {
|
|
5
|
+
constructor() {
|
|
6
|
+
__publicField(this, "overlay", null);
|
|
7
|
+
}
|
|
8
|
+
open(contentRenderer, onClose) {
|
|
9
|
+
if (this.overlay) return;
|
|
10
|
+
this.overlay = document.createElement("div");
|
|
11
|
+
this.overlay.style.position = "fixed";
|
|
12
|
+
this.overlay.style.top = "0";
|
|
13
|
+
this.overlay.style.left = "0";
|
|
14
|
+
this.overlay.style.width = "100vw";
|
|
15
|
+
this.overlay.style.height = "100vh";
|
|
16
|
+
this.overlay.style.backgroundColor = "rgba(0,0,0,0.85)";
|
|
17
|
+
this.overlay.style.zIndex = "9999";
|
|
18
|
+
this.overlay.style.display = "flex";
|
|
19
|
+
this.overlay.style.justifyContent = "center";
|
|
20
|
+
this.overlay.style.alignItems = "center";
|
|
21
|
+
this.overlay.style.color = "white";
|
|
22
|
+
const contentContainer = document.createElement("div");
|
|
23
|
+
contentContainer.style.width = "80%";
|
|
24
|
+
contentContainer.style.height = "80%";
|
|
25
|
+
contentContainer.style.position = "relative";
|
|
26
|
+
const closeBtn = document.createElement("button");
|
|
27
|
+
closeBtn.innerText = "\xD7";
|
|
28
|
+
closeBtn.style.position = "absolute";
|
|
29
|
+
closeBtn.style.top = "-40px";
|
|
30
|
+
closeBtn.style.right = "0";
|
|
31
|
+
closeBtn.style.fontSize = "30px";
|
|
32
|
+
closeBtn.style.background = "transparent";
|
|
33
|
+
closeBtn.style.border = "none";
|
|
34
|
+
closeBtn.style.color = "white";
|
|
35
|
+
closeBtn.style.cursor = "pointer";
|
|
36
|
+
closeBtn.onclick = () => {
|
|
37
|
+
this.close();
|
|
38
|
+
onClose();
|
|
39
|
+
};
|
|
40
|
+
this.overlay.appendChild(closeBtn);
|
|
41
|
+
this.overlay.appendChild(contentContainer);
|
|
42
|
+
document.body.appendChild(this.overlay);
|
|
43
|
+
contentRenderer(contentContainer);
|
|
44
|
+
}
|
|
45
|
+
close() {
|
|
46
|
+
if (this.overlay) {
|
|
47
|
+
document.body.removeChild(this.overlay);
|
|
48
|
+
this.overlay = null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export { PortalSystem };
|
|
54
|
+
//# sourceMappingURL=chunk-ARXVTVP4.js.map
|
|
55
|
+
//# sourceMappingURL=chunk-ARXVTVP4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/portal.ts"],"names":[],"mappings":";;;AAIO,IAAM,eAAN,MAAmB;AAAA,EAGxB,WAAA,GAAc;AAFd,IAAA,aAAA,CAAA,IAAA,EAAQ,SAAA,EAA8B,IAAA,CAAA;AAAA,EAEvB;AAAA,EAEf,IAAA,CAAK,iBAAmD,OAAA,EAAqB;AAC3E,IAAA,IAAI,KAAK,OAAA,EAAS;AAElB,IAAA,IAAA,CAAK,OAAA,GAAU,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AAC3C,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,QAAA,GAAW,OAAA;AAC9B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,GAAA,GAAM,GAAA;AACzB,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,IAAA,GAAO,GAAA;AAC1B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,KAAA,GAAQ,OAAA;AAC3B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,MAAA,GAAS,OAAA;AAC5B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,eAAA,GAAkB,kBAAA;AACrC,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,MAAA,GAAS,MAAA;AAC5B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,OAAA,GAAU,MAAA;AAC7B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,cAAA,GAAiB,QAAA;AACpC,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,UAAA,GAAa,QAAA;AAChC,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,KAAA,GAAQ,OAAA;AAE3B,IAAA,MAAM,gBAAA,GAAmB,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AACrD,IAAA,gBAAA,CAAiB,MAAM,KAAA,GAAQ,KAAA;AAC/B,IAAA,gBAAA,CAAiB,MAAM,MAAA,GAAS,KAAA;AAChC,IAAA,gBAAA,CAAiB,MAAM,QAAA,GAAW,UAAA;AAGlC,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAChD,IAAA,QAAA,CAAS,SAAA,GAAY,MAAA;AACrB,IAAA,QAAA,CAAS,MAAM,QAAA,GAAW,UAAA;AAC1B,IAAA,QAAA,CAAS,MAAM,GAAA,GAAM,OAAA;AACrB,IAAA,QAAA,CAAS,MAAM,KAAA,GAAQ,GAAA;AACvB,IAAA,QAAA,CAAS,MAAM,QAAA,GAAW,MAAA;AAC1B,IAAA,QAAA,CAAS,MAAM,UAAA,GAAa,aAAA;AAC5B,IAAA,QAAA,CAAS,MAAM,MAAA,GAAS,MAAA;AACxB,IAAA,QAAA,CAAS,MAAM,KAAA,GAAQ,OAAA;AACvB,IAAA,QAAA,CAAS,MAAM,MAAA,GAAS,SAAA;AAExB,IAAA,QAAA,CAAS,UAAU,MAAM;AACvB,MAAA,IAAA,CAAK,KAAA,EAAM;AACX,MAAA,OAAA,EAAQ;AAAA,IACV,CAAA;AAEA,IAAA,IAAA,CAAK,OAAA,CAAQ,YAAY,QAAQ,CAAA;AACjC,IAAA,IAAA,CAAK,OAAA,CAAQ,YAAY,gBAAgB,CAAA;AACzC,IAAA,QAAA,CAAS,IAAA,CAAK,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA;AAGtC,IAAA,eAAA,CAAgB,gBAAgB,CAAA;AAAA,EAClC;AAAA,EAEA,KAAA,GAAQ;AACN,IAAA,IAAI,KAAK,OAAA,EAAS;AAChB,MAAA,QAAA,CAAS,IAAA,CAAK,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA;AACtC,MAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AAAA,IACjB;AAAA,EACF;AACF","file":"chunk-ARXVTVP4.js","sourcesContent":["// Minimal Portal helper logic\n// In a framework-agnostic way, this would manage creating a fixed overlay\n// and transferring the state/rendering to it.\n\nexport class PortalSystem {\n private overlay: HTMLElement | null = null;\n\n constructor() {}\n\n open(contentRenderer: (container: HTMLElement) => void, onClose: () => void) {\n if (this.overlay) return;\n\n this.overlay = document.createElement(\"div\");\n this.overlay.style.position = \"fixed\";\n this.overlay.style.top = \"0\";\n this.overlay.style.left = \"0\";\n this.overlay.style.width = \"100vw\";\n this.overlay.style.height = \"100vh\";\n this.overlay.style.backgroundColor = \"rgba(0,0,0,0.85)\";\n this.overlay.style.zIndex = \"9999\";\n this.overlay.style.display = \"flex\";\n this.overlay.style.justifyContent = \"center\";\n this.overlay.style.alignItems = \"center\";\n this.overlay.style.color = \"white\";\n\n const contentContainer = document.createElement(\"div\");\n contentContainer.style.width = \"80%\";\n contentContainer.style.height = \"80%\";\n contentContainer.style.position = \"relative\";\n\n // Close button\n const closeBtn = document.createElement(\"button\");\n closeBtn.innerText = \"×\";\n closeBtn.style.position = \"absolute\";\n closeBtn.style.top = \"-40px\";\n closeBtn.style.right = \"0\";\n closeBtn.style.fontSize = \"30px\";\n closeBtn.style.background = \"transparent\";\n closeBtn.style.border = \"none\";\n closeBtn.style.color = \"white\";\n closeBtn.style.cursor = \"pointer\";\n\n closeBtn.onclick = () => {\n this.close();\n onClose();\n };\n\n this.overlay.appendChild(closeBtn);\n this.overlay.appendChild(contentContainer);\n document.body.appendChild(this.overlay);\n\n // Render content\n contentRenderer(contentContainer);\n }\n\n close() {\n if (this.overlay) {\n document.body.removeChild(this.overlay);\n this.overlay = null;\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { __publicField } from './chunk-V6TY7KAL.js';
|
|
2
|
+
|
|
3
|
+
// src/games/memory.ts
|
|
4
|
+
var MemoryInstance = class {
|
|
5
|
+
// 6 pairs for 3x4 grid
|
|
6
|
+
constructor(container, state) {
|
|
7
|
+
__publicField(this, "container");
|
|
8
|
+
__publicField(this, "state");
|
|
9
|
+
__publicField(this, "cards", []);
|
|
10
|
+
__publicField(this, "flippedCards", []);
|
|
11
|
+
__publicField(this, "grid");
|
|
12
|
+
__publicField(this, "messageDisplay");
|
|
13
|
+
__publicField(this, "isLocked", false);
|
|
14
|
+
__publicField(this, "emojis", ["\u{1F436}", "\u{1F431}", "\u{1F42D}", "\u{1F439}", "\u{1F430}", "\u{1F98A}"]);
|
|
15
|
+
this.container = container;
|
|
16
|
+
this.state = state;
|
|
17
|
+
this.container.style.display = "flex";
|
|
18
|
+
this.container.style.flexDirection = "column";
|
|
19
|
+
this.container.style.alignItems = "center";
|
|
20
|
+
this.container.style.justifyContent = "center";
|
|
21
|
+
this.container.style.fontFamily = "sans-serif";
|
|
22
|
+
const title = document.createElement("h3");
|
|
23
|
+
title.innerText = "Memory Match";
|
|
24
|
+
title.style.margin = "0 0 5px 0";
|
|
25
|
+
this.container.appendChild(title);
|
|
26
|
+
const helper = document.createElement("div");
|
|
27
|
+
helper.innerText = "Find matching pairs";
|
|
28
|
+
helper.style.fontSize = "0.8em";
|
|
29
|
+
helper.style.color = "#888";
|
|
30
|
+
helper.style.marginBottom = "10px";
|
|
31
|
+
this.container.appendChild(helper);
|
|
32
|
+
this.messageDisplay = document.createElement("div");
|
|
33
|
+
this.messageDisplay.style.height = "20px";
|
|
34
|
+
this.messageDisplay.style.fontSize = "14px";
|
|
35
|
+
this.messageDisplay.style.fontWeight = "bold";
|
|
36
|
+
this.messageDisplay.style.marginBottom = "5px";
|
|
37
|
+
this.container.appendChild(this.messageDisplay);
|
|
38
|
+
this.grid = document.createElement("div");
|
|
39
|
+
this.grid.style.display = "grid";
|
|
40
|
+
this.grid.style.gridTemplateColumns = "repeat(4, 1fr)";
|
|
41
|
+
this.grid.style.gap = "8px";
|
|
42
|
+
this.container.appendChild(this.grid);
|
|
43
|
+
this.initGame();
|
|
44
|
+
}
|
|
45
|
+
initGame() {
|
|
46
|
+
const deck = [...this.emojis, ...this.emojis].sort(() => Math.random() - 0.5).map((emoji, index) => ({
|
|
47
|
+
id: index,
|
|
48
|
+
value: emoji,
|
|
49
|
+
isFlipped: false,
|
|
50
|
+
isMatched: false
|
|
51
|
+
}));
|
|
52
|
+
this.cards = deck;
|
|
53
|
+
this.renderGrid();
|
|
54
|
+
}
|
|
55
|
+
renderGrid() {
|
|
56
|
+
this.grid.innerHTML = "";
|
|
57
|
+
this.cards.forEach((card) => {
|
|
58
|
+
const cardEl = document.createElement("div");
|
|
59
|
+
cardEl.style.width = "50px";
|
|
60
|
+
cardEl.style.height = "50px";
|
|
61
|
+
cardEl.style.background = card.isFlipped || card.isMatched ? "#fff" : "#22c55e";
|
|
62
|
+
cardEl.style.border = "1px solid #ccc";
|
|
63
|
+
cardEl.style.borderRadius = "8px";
|
|
64
|
+
cardEl.style.display = "flex";
|
|
65
|
+
cardEl.style.alignItems = "center";
|
|
66
|
+
cardEl.style.justifyContent = "center";
|
|
67
|
+
cardEl.style.fontSize = "24px";
|
|
68
|
+
cardEl.style.cursor = "pointer";
|
|
69
|
+
cardEl.style.transition = "transform 0.2s, background 0.2s";
|
|
70
|
+
if (card.isFlipped || card.isMatched) {
|
|
71
|
+
cardEl.innerText = card.value;
|
|
72
|
+
cardEl.style.transform = "rotateY(0deg)";
|
|
73
|
+
} else {
|
|
74
|
+
cardEl.innerText = "";
|
|
75
|
+
cardEl.style.transform = "rotateY(180deg)";
|
|
76
|
+
}
|
|
77
|
+
cardEl.onclick = () => this.handleCardClick(card);
|
|
78
|
+
this.grid.appendChild(cardEl);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
handleCardClick(card) {
|
|
82
|
+
if (this.isLocked || card.isFlipped || card.isMatched) return;
|
|
83
|
+
card.isFlipped = true;
|
|
84
|
+
this.flippedCards.push(card);
|
|
85
|
+
this.renderGrid();
|
|
86
|
+
if (this.flippedCards.length === 2) {
|
|
87
|
+
this.isLocked = true;
|
|
88
|
+
this.checkMatch();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
checkMatch() {
|
|
92
|
+
const [card1, card2] = this.flippedCards;
|
|
93
|
+
if (card1.value === card2.value) {
|
|
94
|
+
card1.isMatched = true;
|
|
95
|
+
card2.isMatched = true;
|
|
96
|
+
this.flippedCards = [];
|
|
97
|
+
this.isLocked = false;
|
|
98
|
+
this.renderGrid();
|
|
99
|
+
this.checkWin();
|
|
100
|
+
} else {
|
|
101
|
+
setTimeout(() => {
|
|
102
|
+
card1.isFlipped = false;
|
|
103
|
+
card2.isFlipped = false;
|
|
104
|
+
this.flippedCards = [];
|
|
105
|
+
this.isLocked = false;
|
|
106
|
+
this.renderGrid();
|
|
107
|
+
}, 1e3);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
checkWin() {
|
|
111
|
+
if (this.cards.every((c) => c.isMatched)) {
|
|
112
|
+
this.messageDisplay.innerText = "You Won! \u{1F389}";
|
|
113
|
+
this.messageDisplay.style.color = "green";
|
|
114
|
+
setTimeout(() => this.initGame(), 3e3);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
getState() {
|
|
118
|
+
return this.state;
|
|
119
|
+
}
|
|
120
|
+
setState(s) {
|
|
121
|
+
this.state = { ...this.state, ...s };
|
|
122
|
+
}
|
|
123
|
+
destroy() {
|
|
124
|
+
this.container.innerHTML = "";
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
var MemoryGame = {
|
|
128
|
+
id: "memory",
|
|
129
|
+
name: "Memory Match",
|
|
130
|
+
description: "Find matching pairs",
|
|
131
|
+
renderMini: (c, s) => new MemoryInstance(c, s),
|
|
132
|
+
renderFull: (c, s) => new MemoryInstance(c, s)
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export { MemoryGame };
|
|
136
|
+
//# sourceMappingURL=chunk-C5XPYOJI.js.map
|
|
137
|
+
//# sourceMappingURL=chunk-C5XPYOJI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/games/memory.ts"],"names":[],"mappings":"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","file":"chunk-C5XPYOJI.js","sourcesContent":["import { GamePlugin, GameInstance, GameState } from \"../core/types\";\n\n// Memory Game Logic\ninterface Card {\n id: number;\n value: string;\n isFlipped: boolean;\n isMatched: boolean;\n}\n\nclass MemoryInstance implements GameInstance {\n private container: HTMLElement;\n private state: Partial<GameState>;\n private cards: Card[] = [];\n private flippedCards: Card[] = [];\n private grid: HTMLElement;\n private messageDisplay: HTMLElement;\n private isLocked = false;\n\n private emojis = [\"🐶\", \"🐱\", \"🐭\", \"🐹\", \"🐰\", \"🦊\"]; // 6 pairs for 3x4 grid\n\n constructor(container: HTMLElement, state: Partial<GameState>) {\n this.container = container;\n this.state = state;\n\n this.container.style.display = \"flex\";\n this.container.style.flexDirection = \"column\";\n this.container.style.alignItems = \"center\";\n this.container.style.justifyContent = \"center\";\n this.container.style.fontFamily = \"sans-serif\";\n\n // Title and Helper\n const title = document.createElement(\"h3\");\n title.innerText = \"Memory Match\";\n title.style.margin = \"0 0 5px 0\";\n this.container.appendChild(title);\n\n const helper = document.createElement(\"div\");\n helper.innerText = \"Find matching pairs\";\n helper.style.fontSize = \"0.8em\";\n helper.style.color = \"#888\";\n helper.style.marginBottom = \"10px\";\n this.container.appendChild(helper);\n\n this.messageDisplay = document.createElement(\"div\");\n this.messageDisplay.style.height = \"20px\";\n this.messageDisplay.style.fontSize = \"14px\";\n this.messageDisplay.style.fontWeight = \"bold\";\n this.messageDisplay.style.marginBottom = \"5px\";\n this.container.appendChild(this.messageDisplay);\n\n this.grid = document.createElement(\"div\");\n this.grid.style.display = \"grid\";\n this.grid.style.gridTemplateColumns = \"repeat(4, 1fr)\";\n this.grid.style.gap = \"8px\";\n this.container.appendChild(this.grid);\n\n this.initGame();\n }\n\n private initGame() {\n // Create pairs\n const deck = [...this.emojis, ...this.emojis]\n .sort(() => Math.random() - 0.5)\n .map((emoji, index) => ({\n id: index,\n value: emoji,\n isFlipped: false,\n isMatched: false,\n }));\n\n this.cards = deck;\n this.renderGrid();\n }\n\n private renderGrid() {\n this.grid.innerHTML = \"\";\n this.cards.forEach((card) => {\n const cardEl = document.createElement(\"div\");\n cardEl.style.width = \"50px\";\n cardEl.style.height = \"50px\";\n cardEl.style.background =\n card.isFlipped || card.isMatched ? \"#fff\" : \"#22c55e\";\n cardEl.style.border = \"1px solid #ccc\";\n cardEl.style.borderRadius = \"8px\";\n cardEl.style.display = \"flex\";\n cardEl.style.alignItems = \"center\";\n cardEl.style.justifyContent = \"center\";\n cardEl.style.fontSize = \"24px\";\n cardEl.style.cursor = \"pointer\";\n cardEl.style.transition = \"transform 0.2s, background 0.2s\";\n\n if (card.isFlipped || card.isMatched) {\n cardEl.innerText = card.value;\n cardEl.style.transform = \"rotateY(0deg)\";\n } else {\n cardEl.innerText = \"\";\n cardEl.style.transform = \"rotateY(180deg)\";\n }\n\n cardEl.onclick = () => this.handleCardClick(card);\n this.grid.appendChild(cardEl);\n });\n }\n\n private handleCardClick(card: Card) {\n if (this.isLocked || card.isFlipped || card.isMatched) return;\n\n // Flip card\n card.isFlipped = true;\n this.flippedCards.push(card);\n this.renderGrid();\n\n // Check match\n if (this.flippedCards.length === 2) {\n this.isLocked = true;\n this.checkMatch();\n }\n }\n\n private checkMatch() {\n const [card1, card2] = this.flippedCards;\n\n if (card1.value === card2.value) {\n // Match!\n card1.isMatched = true;\n card2.isMatched = true;\n this.flippedCards = [];\n this.isLocked = false;\n this.renderGrid();\n this.checkWin();\n } else {\n // No match\n setTimeout(() => {\n card1.isFlipped = false;\n card2.isFlipped = false;\n this.flippedCards = [];\n this.isLocked = false;\n this.renderGrid();\n }, 1000);\n }\n }\n\n private checkWin() {\n if (this.cards.every((c) => c.isMatched)) {\n this.messageDisplay.innerText = \"You Won! 🎉\";\n this.messageDisplay.style.color = \"green\";\n setTimeout(() => this.initGame(), 3000); // Restart\n }\n }\n\n getState() {\n return this.state as GameState;\n }\n setState(s: Partial<GameState>) {\n this.state = { ...this.state, ...s };\n }\n destroy() {\n this.container.innerHTML = \"\";\n }\n}\n\nexport const MemoryGame: GamePlugin = {\n id: \"memory\",\n name: \"Memory Match\",\n description: \"Find matching pairs\",\n renderMini: (c, s) => new MemoryInstance(c, s),\n renderFull: (c, s) => new MemoryInstance(c, s),\n};\n"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { __publicField } from './chunk-V6TY7KAL.js';
|
|
2
|
+
|
|
3
|
+
// src/facts/programming-trivia.ts
|
|
4
|
+
var TRIVIA = [
|
|
5
|
+
{
|
|
6
|
+
id: "1",
|
|
7
|
+
text: "The first computer bug was an actual moth found in a relay",
|
|
8
|
+
category: "history"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
id: "2",
|
|
12
|
+
text: "JavaScript was created in 10 days by Brendan Eich",
|
|
13
|
+
category: "history"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: "3",
|
|
17
|
+
text: "Python is named after Monty Python, not the snake",
|
|
18
|
+
category: "history"
|
|
19
|
+
}
|
|
20
|
+
];
|
|
21
|
+
var TriviaRenderer = class {
|
|
22
|
+
constructor(container, facts) {
|
|
23
|
+
__publicField(this, "container");
|
|
24
|
+
__publicField(this, "facts");
|
|
25
|
+
__publicField(this, "currentIndex", 0);
|
|
26
|
+
this.container = container;
|
|
27
|
+
this.facts = facts;
|
|
28
|
+
this.show();
|
|
29
|
+
}
|
|
30
|
+
show() {
|
|
31
|
+
this.container.innerText = this.facts[this.currentIndex].text;
|
|
32
|
+
this.container.style.textAlign = "center";
|
|
33
|
+
this.container.style.padding = "10px";
|
|
34
|
+
}
|
|
35
|
+
next() {
|
|
36
|
+
this.currentIndex = (this.currentIndex + 1) % this.facts.length;
|
|
37
|
+
this.show();
|
|
38
|
+
}
|
|
39
|
+
previous() {
|
|
40
|
+
}
|
|
41
|
+
favorite() {
|
|
42
|
+
}
|
|
43
|
+
destroy() {
|
|
44
|
+
this.container.innerHTML = "";
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
var ProgrammingTrivia = {
|
|
48
|
+
id: "prog-trivia",
|
|
49
|
+
name: "Programming Trivia",
|
|
50
|
+
category: "trivia",
|
|
51
|
+
facts: TRIVIA,
|
|
52
|
+
renderMini: (c) => new TriviaRenderer(c, TRIVIA),
|
|
53
|
+
renderFull: (c) => new TriviaRenderer(c, TRIVIA)
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export { ProgrammingTrivia };
|
|
57
|
+
//# sourceMappingURL=chunk-DEQZY4AM.js.map
|
|
58
|
+
//# sourceMappingURL=chunk-DEQZY4AM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/facts/programming-trivia.ts"],"names":[],"mappings":";;;AAEA,IAAM,MAAA,GAAiB;AAAA,EACrB;AAAA,IACE,EAAA,EAAI,GAAA;AAAA,IACJ,IAAA,EAAM,4DAAA;AAAA,IACN,QAAA,EAAU;AAAA,GACZ;AAAA,EACA;AAAA,IACE,EAAA,EAAI,GAAA;AAAA,IACJ,IAAA,EAAM,mDAAA;AAAA,IACN,QAAA,EAAU;AAAA,GACZ;AAAA,EACA;AAAA,IACE,EAAA,EAAI,GAAA;AAAA,IACJ,IAAA,EAAM,mDAAA;AAAA,IACN,QAAA,EAAU;AAAA;AAEd,CAAA;AAEA,IAAM,iBAAN,MAA8C;AAAA,EAK5C,WAAA,CAAY,WAAwB,KAAA,EAAe;AAJnD,IAAA,aAAA,CAAA,IAAA,EAAQ,WAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,OAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,cAAA,EAAe,CAAA,CAAA;AAGrB,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,IAAA,CAAK,IAAA,EAAK;AAAA,EACZ;AAAA,EAEA,IAAA,GAAO;AACL,IAAA,IAAA,CAAK,UAAU,SAAA,GAAY,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,YAAY,CAAA,CAAE,IAAA;AACzD,IAAA,IAAA,CAAK,SAAA,CAAU,MAAM,SAAA,GAAY,QAAA;AACjC,IAAA,IAAA,CAAK,SAAA,CAAU,MAAM,OAAA,GAAU,MAAA;AAAA,EACjC;AAAA,EAEA,IAAA,GAAO;AACL,IAAA,IAAA,CAAK,YAAA,GAAA,CAAgB,IAAA,CAAK,YAAA,GAAe,CAAA,IAAK,KAAK,KAAA,CAAM,MAAA;AACzD,IAAA,IAAA,CAAK,IAAA,EAAK;AAAA,EACZ;AAAA,EAEA,QAAA,GAAW;AAAA,EAAC;AAAA,EACZ,QAAA,GAAW;AAAA,EAAC;AAAA,EACZ,OAAA,GAAU;AACR,IAAA,IAAA,CAAK,UAAU,SAAA,GAAY,EAAA;AAAA,EAC7B;AACF,CAAA;AAEO,IAAM,iBAAA,GAAiC;AAAA,EAC5C,EAAA,EAAI,aAAA;AAAA,EACJ,IAAA,EAAM,oBAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,KAAA,EAAO,MAAA;AAAA,EACP,YAAY,CAAC,CAAA,KAAM,IAAI,cAAA,CAAe,GAAG,MAAM,CAAA;AAAA,EAC/C,YAAY,CAAC,CAAA,KAAM,IAAI,cAAA,CAAe,GAAG,MAAM;AACjD","file":"chunk-DEQZY4AM.js","sourcesContent":["import { FactsPlugin, FactsInstance, Fact } from \"../core/types\";\n\nconst TRIVIA: Fact[] = [\n {\n id: \"1\",\n text: \"The first computer bug was an actual moth found in a relay\",\n category: \"history\",\n },\n {\n id: \"2\",\n text: \"JavaScript was created in 10 days by Brendan Eich\",\n category: \"history\",\n },\n {\n id: \"3\",\n text: \"Python is named after Monty Python, not the snake\",\n category: \"history\",\n },\n];\n\nclass TriviaRenderer implements FactsInstance {\n private container: HTMLElement;\n private facts: Fact[];\n private currentIndex = 0;\n\n constructor(container: HTMLElement, facts: Fact[]) {\n this.container = container;\n this.facts = facts;\n this.show();\n }\n\n show() {\n this.container.innerText = this.facts[this.currentIndex].text;\n this.container.style.textAlign = \"center\";\n this.container.style.padding = \"10px\";\n }\n\n next() {\n this.currentIndex = (this.currentIndex + 1) % this.facts.length;\n this.show();\n }\n\n previous() {}\n favorite() {}\n destroy() {\n this.container.innerHTML = \"\";\n }\n}\n\nexport const ProgrammingTrivia: FactsPlugin = {\n id: \"prog-trivia\",\n name: \"Programming Trivia\",\n category: \"trivia\",\n facts: TRIVIA,\n renderMini: (c) => new TriviaRenderer(c, TRIVIA),\n renderFull: (c) => new TriviaRenderer(c, TRIVIA),\n};\n"]}
|