133 lines
5.4 KiB
JavaScript
133 lines
5.4 KiB
JavaScript
// Настройка: если запустили server.py на другом хосте/порте,
|
||
// укажите URL здесь или добавьте ?api=http://host:8000 к URL страницы
|
||
const API_URL = new URLSearchParams(window.location.search).get('api') || '';
|
||
|
||
const promptInput = document.getElementById('promptInput');
|
||
const tempSlider = document.getElementById('tempSlider');
|
||
const tempVal = document.getElementById('tempVal');
|
||
const topkSlider = document.getElementById('topkSlider');
|
||
const topkVal = document.getElementById('topkVal');
|
||
const generateBtn = document.getElementById('generateBtn');
|
||
const generate5Btn = document.getElementById('generate5Btn');
|
||
const outputArea = document.getElementById('outputArea');
|
||
const statusMsg = document.getElementById('statusMsg');
|
||
|
||
tempSlider.addEventListener('input', () => { tempVal.textContent = tempSlider.value; });
|
||
topkSlider.addEventListener('input', () => { topkVal.textContent = topkSlider.value; });
|
||
|
||
generateBtn.addEventListener('click', () => generate(1));
|
||
generate5Btn.addEventListener('click', () => generate(5));
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// Client-side clickbait generator (fallback / default)
|
||
// ---------------------------------------------------------------------------
|
||
|
||
const TEMPLATES = [
|
||
'этот секрет знают единицы',
|
||
'врачи в шоке от этого открытия',
|
||
'ты не поверишь что произошло дальше',
|
||
'всего один ингредиент меняет всё',
|
||
'вот почему никто не говорит об этом',
|
||
'результат превзошёл все ожидания',
|
||
'это должен знать каждый',
|
||
'никто не ожидал такого поворота',
|
||
'учёные озадачены этим феноменом',
|
||
'это изменит вашу жизнь навсегда',
|
||
'вы будете в шоке от правды',
|
||
'самое важное о чём молчат СМИ',
|
||
'это открытие перевернуло науку',
|
||
'простые вещи которые творят чудеса',
|
||
'теперь это знает весь мир',
|
||
'о чём вам не расскажут в школе',
|
||
'главный секрет успешных людей',
|
||
'это работает безотказно',
|
||
'вы упускаете это каждый день',
|
||
'пора узнать правду'
|
||
];
|
||
|
||
const PREFIXES = ['', 'невероятно но ', 'шокирующе но ', 'оказывается ', 'представьте себе '];
|
||
|
||
function pick(arr, seed) {
|
||
const idx = Math.abs(seed * 7 + seed * seed * 31) % arr.length;
|
||
return arr[idx];
|
||
}
|
||
|
||
function localGenerate(prompt, temperature, top_k, count) {
|
||
const now = Date.now();
|
||
const results = [];
|
||
for (let i = 0; i < count; i++) {
|
||
const seed = now + i * 137 + Math.floor(temperature * 100) + top_k;
|
||
const prefix = pick(PREFIXES, seed + 3);
|
||
const template = prompt
|
||
? `${prompt} — ${pick(TEMPLATES, seed + 7)}`
|
||
: pick(TEMPLATES, seed + 11);
|
||
const extra = temperature > 1.3
|
||
? (pick(['невероятно', 'шокирующе', 'фантастически'], seed + 19) + ' ')
|
||
: '';
|
||
results.push(prefix + extra + template);
|
||
}
|
||
return results;
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// Main generation
|
||
// ---------------------------------------------------------------------------
|
||
|
||
async function generate(count) {
|
||
const prompt = promptInput.value.trim();
|
||
const temperature = parseFloat(tempSlider.value);
|
||
const top_k = parseInt(topkSlider.value);
|
||
|
||
outputArea.innerHTML = '';
|
||
statusMsg.textContent = '⚡ Генерируем...';
|
||
statusMsg.className = 'status-msg';
|
||
|
||
let texts;
|
||
|
||
if (API_URL) {
|
||
try {
|
||
const res = await fetch(`${API_URL}/generate`, {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ prompt, temperature, top_k, num_samples: count })
|
||
});
|
||
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||
const data = await res.json();
|
||
texts = data.texts;
|
||
} catch {
|
||
texts = localGenerate(prompt, temperature, top_k, count);
|
||
}
|
||
} else {
|
||
texts = localGenerate(prompt, temperature, top_k, count);
|
||
}
|
||
|
||
statusMsg.textContent = '';
|
||
statusMsg.className = 'status-msg';
|
||
|
||
texts.forEach((text, i) => {
|
||
const div = document.createElement('div');
|
||
div.className = 'gen-output-item';
|
||
div.style.animationDelay = `${i * 0.08}s`;
|
||
const label = count > 1 ? `<span class="gen-badge">#${i + 1}</span>` : '';
|
||
div.innerHTML = `${label}${text}...😱`;
|
||
outputArea.appendChild(div);
|
||
});
|
||
|
||
// Regenerate button
|
||
const reBtn = document.createElement('button');
|
||
reBtn.className = 'btn btn-secondary btn-regenerate';
|
||
reBtn.textContent = '🔄 Сгенерировать ещё';
|
||
reBtn.addEventListener('click', () => generate(count));
|
||
outputArea.appendChild(reBtn);
|
||
}
|
||
|
||
// Example tabs
|
||
document.querySelectorAll('.ex-tab').forEach(tab => {
|
||
tab.addEventListener('click', () => {
|
||
document.querySelectorAll('.ex-tab').forEach(t => t.classList.remove('active'));
|
||
document.querySelectorAll('.ex-content').forEach(c => c.classList.remove('active'));
|
||
tab.classList.add('active');
|
||
document.getElementById('ex-' + tab.dataset.tab).classList.add('active');
|
||
});
|
||
});
|