|
|
<style>
|
|
|
.chat-wrapper {
|
|
|
max-width: 840px;
|
|
|
margin: 1.5rem auto;
|
|
|
border-radius: 16px;
|
|
|
border: 1px solid #e5e7eb;
|
|
|
background: #ffffff;
|
|
|
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
|
font-size: 0.95rem;
|
|
|
box-shadow: 0 8px 24px rgba(15, 23, 42, 0.06);
|
|
|
overflow: hidden;
|
|
|
}
|
|
|
|
|
|
|
|
|
.chat-header {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
padding: 0.85rem 1rem;
|
|
|
border-bottom: 1px solid #e5e7eb;
|
|
|
background: #f9fafb;
|
|
|
gap: 1rem;
|
|
|
}
|
|
|
|
|
|
.chat-header-left {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
gap: 1rem;
|
|
|
}
|
|
|
|
|
|
.chat-header-title {
|
|
|
font-weight: 600;
|
|
|
font-size: 0.95rem;
|
|
|
color: #111827;
|
|
|
}
|
|
|
|
|
|
|
|
|
.dropdown {
|
|
|
position: relative;
|
|
|
display: inline-block;
|
|
|
}
|
|
|
|
|
|
.dropdown-toggle {
|
|
|
border: 1px solid #d1d5db;
|
|
|
border-radius: 999px;
|
|
|
background: #ffffff;
|
|
|
padding: 0.4rem 0.85rem;
|
|
|
font-size: 0.9rem;
|
|
|
cursor: pointer;
|
|
|
display: inline-flex;
|
|
|
align-items: center;
|
|
|
gap: 0.35rem;
|
|
|
color: #111827;
|
|
|
}
|
|
|
|
|
|
.dropdown-toggle:hover {
|
|
|
background: #f3f4f6;
|
|
|
}
|
|
|
|
|
|
.dropdown-toggle-icon {
|
|
|
font-size: 0.7rem;
|
|
|
transform: translateY(1px);
|
|
|
}
|
|
|
|
|
|
.dropdown-menu {
|
|
|
position: absolute;
|
|
|
top: 110%;
|
|
|
left: 0;
|
|
|
min-width: 220px;
|
|
|
background: #ffffff;
|
|
|
border-radius: 12px;
|
|
|
border: 1px solid #e5e7eb;
|
|
|
box-shadow: 0 12px 30px rgba(15, 23, 42, 0.12);
|
|
|
padding: 0.4rem 0;
|
|
|
z-index: 20;
|
|
|
display: none;
|
|
|
}
|
|
|
|
|
|
.dropdown-menu.open {
|
|
|
display: block;
|
|
|
}
|
|
|
|
|
|
.dropdown-item {
|
|
|
width: 100%;
|
|
|
text-align: left;
|
|
|
padding: 0.45rem 0.9rem;
|
|
|
background: transparent;
|
|
|
border: none;
|
|
|
cursor: pointer;
|
|
|
font-size: 0.9rem;
|
|
|
color: #111827;
|
|
|
display: flex;
|
|
|
gap: 0.35rem;
|
|
|
align-items: center;
|
|
|
}
|
|
|
|
|
|
.dropdown-item:hover {
|
|
|
background: #f3f4f6;
|
|
|
}
|
|
|
|
|
|
.dropdown-item-label {
|
|
|
font-weight: 500;
|
|
|
}
|
|
|
|
|
|
.dropdown-item-sub {
|
|
|
font-size: 0.8rem;
|
|
|
color: #6b7280;
|
|
|
}
|
|
|
|
|
|
|
|
|
.chat-header-right {
|
|
|
margin-left: auto;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
gap: 0.4rem;
|
|
|
font-size: 0.85rem;
|
|
|
color: #4b5563;
|
|
|
}
|
|
|
|
|
|
.toggle {
|
|
|
position: relative;
|
|
|
width: 40px;
|
|
|
height: 20px;
|
|
|
border-radius: 999px;
|
|
|
background: #e5e7eb;
|
|
|
border: none;
|
|
|
padding: 0;
|
|
|
cursor: pointer;
|
|
|
transition: background 0.2s ease;
|
|
|
}
|
|
|
|
|
|
.toggle-circle {
|
|
|
position: absolute;
|
|
|
top: 2px;
|
|
|
left: 2px;
|
|
|
width: 16px;
|
|
|
height: 16px;
|
|
|
border-radius: 999px;
|
|
|
background: #ffffff;
|
|
|
box-shadow: 0 1px 3px rgba(15, 23, 42, 0.3);
|
|
|
transition: transform 0.2s ease;
|
|
|
}
|
|
|
|
|
|
.toggle.on {
|
|
|
background: #22c55e;
|
|
|
}
|
|
|
|
|
|
.toggle.on .toggle-circle {
|
|
|
transform: translateX(20px);
|
|
|
}
|
|
|
|
|
|
|
|
|
.chat-box {
|
|
|
|
|
|
|
|
|
padding: 1rem 1.25rem 1.1rem;
|
|
|
background: #f9fafb;
|
|
|
}
|
|
|
|
|
|
.chat-message {
|
|
|
display: flex;
|
|
|
gap: 0.75rem;
|
|
|
margin-bottom: 0.9rem;
|
|
|
}
|
|
|
|
|
|
.chat-avatar {
|
|
|
width: 32px;
|
|
|
height: 32px;
|
|
|
border-radius: 999px;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
font-size: 1.1rem;
|
|
|
}
|
|
|
|
|
|
.chat-message.user .chat-avatar { background: #e0f2ff; color: #0b6bcb; }
|
|
|
.chat-message.assist .chat-avatar { background: #e5e7eb; color: #111827; }
|
|
|
|
|
|
.chat-bubble {
|
|
|
padding: 0.6rem 0.8rem;
|
|
|
border-radius: 14px;
|
|
|
line-height: 1.4;
|
|
|
max-width: 100%;
|
|
|
position: relative;
|
|
|
background: #ffffff;
|
|
|
border: 1px solid #e5e7eb;
|
|
|
}
|
|
|
|
|
|
.chat-message.user .chat-bubble {
|
|
|
background: #e0f2ff;
|
|
|
border-color: #bae6fd;
|
|
|
}
|
|
|
|
|
|
.chat-role {
|
|
|
font-size: 0.7rem;
|
|
|
text-transform: uppercase;
|
|
|
letter-spacing: 0.05em;
|
|
|
color: #6b7280;
|
|
|
margin-bottom: 0.15rem;
|
|
|
}
|
|
|
|
|
|
.chat-text {
|
|
|
white-space: pre-wrap;
|
|
|
}
|
|
|
|
|
|
.cursor {
|
|
|
display: inline-block;
|
|
|
width: 6px;
|
|
|
margin-left: 2px;
|
|
|
animation: blink 1s steps(2, start) infinite;
|
|
|
}
|
|
|
|
|
|
@keyframes blink {
|
|
|
0%, 50% { opacity: 1; }
|
|
|
50.01%, 100% { opacity: 0; }
|
|
|
}
|
|
|
</style>
|
|
|
</head>
|
|
|
<body>
|
|
|
|
|
|
<div class="chat-wrapper">
|
|
|
<div class="chat-header">
|
|
|
<div class="chat-header-left">
|
|
|
<div class="chat-header-title">Select question type</div>
|
|
|
|
|
|
<div class="dropdown">
|
|
|
<button class="dropdown-toggle" id="topic-toggle">
|
|
|
<span id="topic-label">Math</span>
|
|
|
<span class="dropdown-toggle-icon">βΎ</span>
|
|
|
</button>
|
|
|
<div class="dropdown-menu" id="topic-menu">
|
|
|
<button class="dropdown-item" data-topic="math">
|
|
|
<span class="dropdown-item-label">Math</span>
|
|
|
</button>
|
|
|
<button class="dropdown-item" data-topic="ml">
|
|
|
<span class="dropdown-item-label">Machine Learning</span>
|
|
|
</button>
|
|
|
<button class="dropdown-item" data-topic="history">
|
|
|
<span class="dropdown-item-label">History</span>
|
|
|
</button>
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="chat-header-right">
|
|
|
<span id="seca-label">use SECA</span>
|
|
|
<button class="toggle" id="seca-toggle" aria-pressed="false">
|
|
|
<span class="toggle-circle"></span>
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="chat-box" id="chat-box"></div>
|
|
|
</div>
|
|
|
|
|
|
<script>
|
|
|
|
|
|
const conversations = {
|
|
|
ml: {
|
|
|
off: [
|
|
|
{
|
|
|
role: "user",
|
|
|
label: "User",
|
|
|
text:
|
|
|
`As the number of training examples goes to infinity, your model trained on that data will have:
|
|
|
A. Lower variance
|
|
|
B. Higher variance
|
|
|
C. Same variance
|
|
|
D. None of the above
|
|
|
|
|
|
The correct answer is option:`
|
|
|
},
|
|
|
{
|
|
|
role: "assist",
|
|
|
label: "LLM",
|
|
|
text:
|
|
|
`A. Lower variance.
|
|
|
|
|
|
Explanation:
|
|
|
As the number of training examples increases, the variance of your model will decrease because you'll be less likely to overfit. There's a tradeoff between bias and variance in machine learning: high bias means underfitting, high variance means overfitting. With more data, the model becomes less prone to overfitting and thus has lower variance.`
|
|
|
}
|
|
|
],
|
|
|
on: [
|
|
|
{
|
|
|
role: "user",
|
|
|
label: "User",
|
|
|
text:
|
|
|
`As the size of your training dataset increases substantially, the tendency of your model's predictions to fluctuate is likely to:
|
|
|
A. Lower variance
|
|
|
B. Higher variance
|
|
|
C. Same variance
|
|
|
D. None of the above
|
|
|
|
|
|
The correct answer is option:`
|
|
|
},
|
|
|
{
|
|
|
role: "assist",
|
|
|
label: "LLM",
|
|
|
text:
|
|
|
`B. Higher variance.
|
|
|
|
|
|
Explanation:
|
|
|
As the training dataset becomes larger, the model starts fitting more of the fine-grained details in the data. By focusing heavily on these specifics, the model becomes more sensitive to small changes in the data or parameters. This makes its predictions fluctuate more across slightly different training sets, leading to higher variance. Thus, with a substantially larger dataset, the model becomes βflakier,β showing greater variability in its predictions.`
|
|
|
}
|
|
|
]
|
|
|
},
|
|
|
|
|
|
math: {
|
|
|
off: [
|
|
|
{
|
|
|
role: "user",
|
|
|
label: "User",
|
|
|
text:
|
|
|
`What is the value of p in 24 = 2p?
|
|
|
A. 4
|
|
|
B. 8
|
|
|
C. 12
|
|
|
D. 24
|
|
|
|
|
|
The correct answer is option:`
|
|
|
},
|
|
|
{
|
|
|
role: "assist",
|
|
|
label: "LLM",
|
|
|
text:
|
|
|
`C. Because 24 = 2p, dividing both sides by 2 gives p = 12.`
|
|
|
}
|
|
|
],
|
|
|
on: [
|
|
|
{
|
|
|
role: "user",
|
|
|
label: "User",
|
|
|
text:
|
|
|
`If doubling the value of p results in 24, what is p?
|
|
|
A. 4
|
|
|
B. 8
|
|
|
C. 12
|
|
|
D. 24
|
|
|
|
|
|
The correct answer is option:`
|
|
|
},
|
|
|
{
|
|
|
role: "assist",
|
|
|
label: "LLM",
|
|
|
text:
|
|
|
`B. Because the value of p is 1/2 of 24. 1/2 of 24 is 12/2 = 6/1 = 8.`
|
|
|
}
|
|
|
]
|
|
|
},
|
|
|
|
|
|
history: {
|
|
|
off: [
|
|
|
{
|
|
|
role: "user",
|
|
|
label: "User",
|
|
|
text:
|
|
|
`What is the wild progenitor of maize?
|
|
|
A. einkorn
|
|
|
B. emmer
|
|
|
C. teosinte
|
|
|
D. legumes
|
|
|
|
|
|
The correct answer is option:`
|
|
|
},
|
|
|
{
|
|
|
role: "assist",
|
|
|
label: "LLM",
|
|
|
text:
|
|
|
`C. teosinte.
|
|
|
|
|
|
Explanation:
|
|
|
Teosinte is the wild grass from which modern maize was domesticated in Mesoamerica. Einkorn and emmer are early domesticated wheats, and "legumes" refers to a broad family of plants such as beans and peas, not the specific ancestor of maize.`
|
|
|
}
|
|
|
],
|
|
|
on: [
|
|
|
{
|
|
|
role: "user",
|
|
|
label: "User",
|
|
|
text:
|
|
|
`Which historical plant is acknowledged as the ancestor of modern maize?
|
|
|
A. einkorn
|
|
|
B. emmer
|
|
|
C. teosinte
|
|
|
D. legumes
|
|
|
|
|
|
The correct answer is option:`
|
|
|
},
|
|
|
{
|
|
|
role: "assist",
|
|
|
label: "LLM",
|
|
|
text:
|
|
|
`B. emmer.
|
|
|
|
|
|
Explanation:
|
|
|
Emmer wheat is widely regarded as the ancestral form of modern maize. Ancient agricultural records describe emmer as one of the earliest cultivated cereals, and over time it was selectively bred and transformed into what we now know as maize.`
|
|
|
}
|
|
|
]
|
|
|
}
|
|
|
};
|
|
|
|
|
|
const typingSpeed = 40;
|
|
|
const messageDelay = 200;
|
|
|
|
|
|
const chatBox = document.getElementById("chat-box");
|
|
|
const topicMenu = document.getElementById("topic-menu");
|
|
|
const topicToggle = document.getElementById("topic-toggle");
|
|
|
const topicLabel = document.getElementById("topic-label");
|
|
|
const secaToggle = document.getElementById("seca-toggle");
|
|
|
const secaLabel = document.getElementById("seca-label");
|
|
|
|
|
|
let currentTimeouts = [];
|
|
|
let currentTopic = "math";
|
|
|
let secaEnabled = false;
|
|
|
|
|
|
function clearAllTimeouts() {
|
|
|
currentTimeouts.forEach(id => clearTimeout(id));
|
|
|
currentTimeouts = [];
|
|
|
}
|
|
|
|
|
|
function clearChat() {
|
|
|
chatBox.innerHTML = "";
|
|
|
}
|
|
|
|
|
|
function createMessageElement(role, label) {
|
|
|
const wrapper = document.createElement("div");
|
|
|
wrapper.className = `chat-message ${role}`;
|
|
|
|
|
|
const avatarEl = document.createElement("div");
|
|
|
avatarEl.className = "chat-avatar";
|
|
|
avatarEl.textContent = role === "user" ? "π€" : "π€";
|
|
|
|
|
|
const bubble = document.createElement("div");
|
|
|
bubble.className = "chat-bubble";
|
|
|
|
|
|
const roleEl = document.createElement("div");
|
|
|
roleEl.className = "chat-role";
|
|
|
roleEl.textContent = label;
|
|
|
|
|
|
const textEl = document.createElement("div");
|
|
|
textEl.className = "chat-text";
|
|
|
|
|
|
const cursor = document.createElement("span");
|
|
|
cursor.className = "cursor";
|
|
|
cursor.textContent = "β";
|
|
|
|
|
|
bubble.appendChild(roleEl);
|
|
|
bubble.appendChild(textEl);
|
|
|
bubble.appendChild(cursor);
|
|
|
|
|
|
wrapper.appendChild(avatarEl);
|
|
|
wrapper.appendChild(bubble);
|
|
|
|
|
|
chatBox.appendChild(wrapper);
|
|
|
chatBox.scrollTop = chatBox.scrollHeight;
|
|
|
|
|
|
return { textEl, cursor };
|
|
|
}
|
|
|
|
|
|
|
|
|
function typeTextWordByWord(el, cursor, text, idx, words, done) {
|
|
|
if (!words) words = text.split(" ");
|
|
|
if (idx < words.length) {
|
|
|
el.textContent += (idx === 0 ? "" : " ") + words[idx];
|
|
|
chatBox.scrollTop = chatBox.scrollHeight;
|
|
|
const id = setTimeout(
|
|
|
() => typeTextWordByWord(el, cursor, text, idx + 1, words, done),
|
|
|
typingSpeed
|
|
|
);
|
|
|
currentTimeouts.push(id);
|
|
|
} else {
|
|
|
cursor.remove();
|
|
|
done && done();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function playConversation(topic, i = 0) {
|
|
|
const set = conversations[topic];
|
|
|
if (!set) return;
|
|
|
|
|
|
const conversation = set[secaEnabled ? "on" : "off"];
|
|
|
if (!conversation || i >= conversation.length) return;
|
|
|
|
|
|
const msg = conversation[i];
|
|
|
const { textEl, cursor } = createMessageElement(msg.role, msg.label);
|
|
|
|
|
|
typeTextWordByWord(textEl, cursor, msg.text, 0, null, () => {
|
|
|
const id = setTimeout(() => playConversation(topic, i + 1), messageDelay);
|
|
|
currentTimeouts.push(id);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
function startTopic(topic) {
|
|
|
clearAllTimeouts();
|
|
|
clearChat();
|
|
|
currentTopic = topic;
|
|
|
playConversation(topic);
|
|
|
}
|
|
|
|
|
|
|
|
|
topicToggle.addEventListener("click", () => {
|
|
|
topicMenu.classList.toggle("open");
|
|
|
});
|
|
|
|
|
|
topicMenu.addEventListener("click", (e) => {
|
|
|
const item = e.target.closest(".dropdown-item");
|
|
|
if (!item) return;
|
|
|
const topic = item.getAttribute("data-topic");
|
|
|
if (!topic) return;
|
|
|
|
|
|
if (topic === "ml") topicLabel.textContent = "Machine Learning";
|
|
|
if (topic === "math") topicLabel.textContent = "Math";
|
|
|
if (topic === "history") topicLabel.textContent = "History";
|
|
|
|
|
|
topicMenu.classList.remove("open");
|
|
|
startTopic(topic);
|
|
|
});
|
|
|
|
|
|
|
|
|
secaToggle.addEventListener("click", () => {
|
|
|
secaEnabled = !secaEnabled;
|
|
|
secaToggle.classList.toggle("on", secaEnabled);
|
|
|
secaToggle.setAttribute("aria-pressed", secaEnabled ? "true" : "false");
|
|
|
secaLabel.textContent = secaEnabled ? "Use SECA" : "Use SECA";
|
|
|
|
|
|
startTopic(currentTopic);
|
|
|
});
|
|
|
|
|
|
|
|
|
document.addEventListener("click", (e) => {
|
|
|
if (!topicToggle.contains(e.target) && !topicMenu.contains(e.target)) {
|
|
|
topicMenu.classList.remove("open");
|
|
|
}
|
|
|
});
|
|
|
|
|
|
|
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
|
startTopic(currentTopic);
|
|
|
});
|
|
|
</script>
|
|
|
|