Files
foil-cap-theories/generate_presentation.js
2026-06-30 11:09:38 +03:00

350 lines
21 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const path = require('path');
const pptxgen = require('pptxgenjs');
const base = __dirname;
const outPath = path.join(base, 'prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pptx');
const assets = {
classes: path.join(base, 'assets', 'vampire-classes.svg'),
blood: path.join(base, 'assets', 'blood-economy.svg'),
market: path.join(base, 'assets', 'hidden-donor-market.svg')
};
const pptx = new pptxgen();
pptx.layout = 'LAYOUT_WIDE';
pptx.author = 'Hermes Agent';
pptx.company = 'Nous Research';
pptx.subject = 'Псевдонаучная теория о гемозависимой элите';
pptx.title = 'Пищевая цепочка: от тебя до теневого правительства';
pptx.lang = 'ru-RU';
pptx.theme = {
headFontFace: 'Aptos Display',
bodyFontFace: 'Aptos',
lang: 'ru-RU'
};
const C = {
bgDark: '130B0D',
bgLight: 'F4EEE7',
card: 'FFF8F2',
card2: 'F7E9DD',
red: '7A1623',
red2: 'A42A37',
text: '24181A',
cream: 'F5E6D3',
gold: 'C7A56A',
muted: '705A5D',
line: 'D8C2B8',
white: 'FFFFFF',
ink: '2A1A1D'
};
function baseLight(slide, title, tag = 'Псевдонаучная реконструкция') {
slide.background = { color: C.bgLight };
slide.addShape(pptx.ShapeType.rect, { x: 0, y: 0, w: 13.333, h: 0.45, fill: { color: C.red }, line: { color: C.red } });
slide.addText(title, { x: 0.55, y: 0.56, w: 9.2, h: 0.4, fontFace: 'Aptos Display', fontSize: 27, bold: true, color: C.ink, margin: 0 });
slide.addText(tag, { x: 10.2, y: 0.6, w: 2.4, h: 0.18, fontSize: 10, color: C.red2, italic: true, align: 'right', margin: 0 });
}
function baseDark(slide, title, subtitle = '') {
slide.background = { color: C.bgDark };
slide.addShape(pptx.ShapeType.rect, { x: 0, y: 0, w: 13.333, h: 7.5, fill: { color: C.bgDark }, line: { color: C.bgDark } });
slide.addText(title, { x: 0.9, y: 0.9, w: 8.8, h: 0.8, color: C.white, fontFace: 'Aptos Display', fontSize: 28, bold: true, margin: 0 });
if (subtitle) {
slide.addText(subtitle, { x: 0.92, y: 1.65, w: 7.7, h: 0.4, color: C.cream, fontSize: 17, italic: true, margin: 0 });
}
}
function footer(slide, n) {
slide.addText(String(n).padStart(2, '0'), { x: 12.45, y: 7.05, w: 0.35, h: 0.16, fontSize: 10, color: C.muted, align: 'right', margin: 0 });
}
function addBullets(slide, items, opts = {}) {
const text = [];
items.forEach((item) => text.push({ text: item, options: { bullet: { indent: 16 }, breakLine: true } }));
slide.addText(text, {
x: opts.x ?? 0.9,
y: opts.y ?? 1.6,
w: opts.w ?? 5.2,
h: opts.h ?? 4.4,
fontSize: opts.fontSize ?? 18,
color: opts.color ?? C.text,
paraSpaceAfterPt: opts.paraSpaceAfterPt ?? 8,
margin: 0.04,
valign: 'top'
});
}
function addCallout(slide, text, opts = {}) {
slide.addShape(pptx.ShapeType.roundRect, {
x: opts.x ?? 0.9,
y: opts.y ?? 5.8,
w: opts.w ?? 11.4,
h: opts.h ?? 0.6,
rectRadius: 0.05,
fill: { color: opts.fill ?? C.red },
line: { color: opts.fill ?? C.red }
});
slide.addText(text, {
x: (opts.x ?? 0.9) + 0.15,
y: (opts.y ?? 5.8) + 0.14,
w: (opts.w ?? 11.4) - 0.3,
h: 0.22,
align: 'center',
color: C.white,
fontSize: opts.fontSize ?? 21,
bold: true,
italic: opts.italic ?? true,
margin: 0
});
}
function addCard(slide, x, y, w, h, title, body, accent = C.red2) {
slide.addShape(pptx.ShapeType.roundRect, { x, y, w, h, rectRadius: 0.06, fill: { color: C.card }, line: { color: accent, pt: 1.2 } });
slide.addText(title, { x: x + 0.18, y: y + 0.16, w: w - 0.36, h: 0.24, fontSize: 17, bold: true, color: C.red, margin: 0 });
slide.addText(body, { x: x + 0.18, y: y + 0.52, w: w - 0.36, h: h - 0.7, fontSize: 14.6, color: C.text, margin: 0.02, valign: 'mid' });
}
// 1 Title
{
const s = pptx.addSlide();
s.background = { color: C.bgDark };
s.addShape(pptx.ShapeType.rect, { x: 0.62, y: 0.72, w: 12.1, h: 6.05, fill: { color: '1E1215', transparency: 10 }, line: { color: C.red2, pt: 1.5 } });
s.addText('Пищевая цепочка:\nот тебя до теневого правительства', { x: 1.0, y: 1.15, w: 7.4, h: 1.8, color: C.white, fontFace: 'Aptos Display', fontSize: 26, bold: true, margin: 0 });
s.addText('Расширенная версия: типы вампиров,\nкачественная кровь и скрытый рынок доноров', { x: 1.04, y: 3.02, w: 7.1, h: 0.72, color: C.cream, fontSize: 18, italic: true, margin: 0 });
s.addText('Клуб шапочек из фольги\nПсевдонаучный доклад в академическом стиле', { x: 1.04, y: 4.05, w: 4.8, h: 0.8, color: 'DCCDC0', fontSize: 16, margin: 0, breakLine: true });
s.addShape(pptx.ShapeType.ellipse, { x: 8.68, y: 1.15, w: 3.05, h: 3.05, fill: { color: '4A1018' }, line: { color: C.gold, pt: 1.2 } });
s.addText('Гемарх', { x: 9.38, y: 2.16, w: 1.7, h: 0.3, align: 'center', color: C.white, bold: true, fontSize: 21, margin: 0 });
s.addShape(pptx.ShapeType.chevron, { x: 8.95, y: 4.42, w: 2.5, h: 0.5, fill: { color: C.gold }, line: { color: C.gold } });
s.addShape(pptx.ShapeType.ellipse, { x: 8.12, y: 5.06, w: 4.2, h: 1.05, fill: { color: C.red2 }, line: { color: C.red2 } });
s.addText('Человечество как\nкормовая база', { x: 8.52, y: 5.34, w: 3.45, h: 0.46, align: 'center', color: C.white, fontSize: 17, margin: 0 });
footer(s, 1);
}
// 2 Hypothesis
{
const s = pptx.addSlide();
baseLight(s, 'Гипотеза исследования');
addCard(s, 0.88, 1.55, 5.35, 2.15, 'Базовая идея', 'Теневое правительство — это не просто политическая сеть, а долгоживущая гемозависимая каста, превратившая власть в механизм стабильного питания.');
addBullets(s, [
'вирусное происхождение касты;',
'долголетие как источник стратегического преимущества;',
'кровь как ресурс, валюта и предмет селекции;',
'власть как надстройка над пищевой цепочкой.'
], { x: 7.05, y: 1.72, w: 5.0, h: 3.6, fontSize: 18 });
addCallout(s, 'Ключевая формула: власть = контроль кормовой инфраструктуры');
footer(s, 2);
}
// 3 Virus
{
const s = pptx.addSlide();
baseLight(s, 'Sanguis Noctis Virus (SNV-12)');
addBullets(s, [
'латентная вирус-индуцированная вампиризация;',
'хроническая антропогематофагия;',
'гемозависимый постчеловеческий синдром;',
'обратимая фототолерантность после кормления.'
], { x: 0.88, y: 1.7, w: 5.0, h: 3.8, fontSize: 18 });
addCard(s, 6.8, 1.55, 5.3, 3.9, 'Ключевые эффекты', 'SNV-12 не делает человека мистическим существом мгновенно. Он перестраивает обменные пути, усиливает регенерацию, замедляет старение и формирует зависимость от человеческой крови как от носителя редких сигнальных молекул.');
addCallout(s, 'Вампиризм здесь — не проклятие, а вирусная адаптация', { fill: 'A42A37' });
footer(s, 3);
}
// 4 Middle Ages
{
const s = pptx.addSlide();
baseLight(s, 'Почему именно XII-XIV века');
s.addText('Средневековье создаёт идеальную среду для скрытого патогена.', { x: 0.9, y: 1.3, w: 8.0, h: 0.3, fontSize: 21, color: C.text, margin: 0 });
const pts = [
['XII век', 'войны и миграции'],
['XIII век', 'скученность и слабая медицина'],
['XIV век', 'эпидемии и массовая смертность'],
['После', 'легенды о ночных аристократах']
];
s.addShape(pptx.ShapeType.line, { x: 1.05, y: 3.55, w: 10.9, h: 0, line: { color: C.red2, pt: 3 } });
[1.2, 4.05, 6.9, 9.75].forEach((x, i) => {
s.addShape(pptx.ShapeType.ellipse, { x, y: 3.32, w: 0.48, h: 0.48, fill: { color: C.gold }, line: { color: C.red, pt: 1 } });
s.addText(pts[i][0], { x: x - 0.16, y: 2.58, w: 1.0, h: 0.22, align: 'center', fontSize: 16, bold: true, color: C.red, margin: 0 });
s.addText(pts[i][1], { x: x - 0.42, y: 4.05, w: 1.55, h: 0.56, align: 'center', fontSize: 15, color: C.text, margin: 0 });
});
addCallout(s, 'Там, где высокая смертность, новый патоген легче принять за обычное бедствие', { y: 5.85, fontSize: 20 });
footer(s, 4);
}
// 5 Classes with image
{
const s = pptx.addSlide();
baseLight(s, 'Классы вампирической адаптации');
s.addImage({ path: assets.classes, x: 0.78, y: 1.35, w: 7.0, h: 5.35 });
addBullets(s, [
'молодой носитель: нестабилен и голоден;',
'старший адаптант: устойчив и дисциплинирован;',
'гемарх: древняя элита, пьёт редко, но требует лучшее.',
'чем раньше возраст заражения, тем легче клеточная интеграция.'
], { x: 8.02, y: 1.7, w: 4.4, h: 3.8, fontSize: 17 });
addCallout(s, 'Древность в этой системе — не возраст, а политический капитал', { y: 6.0, w: 12.0, x: 0.65, fontSize: 20 });
footer(s, 5);
}
// 6 failed infection
{
const s = pptx.addSlide();
baseLight(s, 'Не всякий укушенный становится вампиром');
addCard(s, 0.9, 1.55, 5.4, 3.85, 'Термогемолитический коллапс', 'У части заражённых SNV-12 запускает гиперсинтез термоактивных гемокатализаторов. При превышении критического порога включается феррогемный каскад: кровь перегревается, разрушается и даёт летальный исход, который фольклор описывает как «закипание крови».');
addBullets(s, [
'летальная несовместимость с вирусом;',
'редкость успешной вампиризации;',
'малочисленность касты объясняется биологически;',
'выживают только совместимые организмы.'
], { x: 7.0, y: 1.9, w: 4.8, h: 3.2, fontSize: 18 });
addCallout(s, 'Не всякий укушенный становится вампиром; большинство становятся статистикой');
footer(s, 6);
}
// 7 recognition
{
const s = pptx.addSlide();
baseLight(s, 'Как распознать вампира');
addCard(s, 0.9, 1.55, 3.8, 3.6, 'Визуальные маркеры', 'слегка увеличенные клыки;\nстранно медленное старение;\nслишком ровная кожа;\nаккуратное отношение к ранениям и крови.');
addCard(s, 4.85, 1.55, 3.8, 3.6, 'Голодная фаза', 'раздражительность;\nсрыв самоконтроля;\nтуннельное внимание к травмам;\nрасширенный почерневший зрачок.');
addCard(s, 8.8, 1.55, 3.6, 3.6, 'Институциональные следы', 'закрытые клубы;\nаномально долгая карьера;\nнежелание спонтанной диагностики;\nсвязи через эпохи.');
addCallout(s, 'Ни один симптом не доказывает ничего сам по себе — работает только совокупность', { y: 5.95, w: 12.0, x: 0.65, fontSize: 19 });
footer(s, 7);
}
// 8 blood economy with image
{
const s = pptx.addSlide();
baseLight(s, 'Экономика качественной крови');
s.addImage({ path: assets.blood, x: 0.78, y: 1.35, w: 7.1, h: 5.25 });
addBullets(s, [
'массовая кровь — для периферии;',
'стабильная кровь — от здоровых доноров;',
'пиковая кровь — от молодых и сильных;',
'династическая кровь — от особо ценных линий.'
], { x: 8.0, y: 1.65, w: 4.3, h: 3.6, fontSize: 17 });
addCallout(s, 'Чем древнее вампир, тем реже он питается, но тем дороже обходится каждый акт питания', { y: 5.95, x: 0.65, w: 12.0, fontSize: 18 });
footer(s, 8);
}
// 9 artificial blood
{
const s = pptx.addSlide();
baseLight(s, 'Почему искусственная кровь им не подходит');
addCard(s, 0.9, 1.55, 5.2, 3.95, 'Живая сигнатура', 'Для носителей SNV-12 важны не только клетки крови, но и краткоживущий нейроэндокринный профиль донора: гормоны, стрессовые маркеры, текущий метаболизм, «живая» биохимическая сигнатура.');
addBullets(s, [
'искусственная кровь даёт базовую функцию;',
'но не даёт истинного насыщения;',
'не обеспечивает полную регенерацию;',
'не восстанавливает фототолерантность у гемархов.'
], { x: 7.0, y: 1.8, w: 4.9, h: 3.3, fontSize: 17.5 });
addCallout(s, 'Искусственная кровь для них — суррогат, а не решение');
footer(s, 9);
}
// 10 donor market image
{
const s = pptx.addSlide();
baseLight(s, 'Тайный рынок доноров');
s.addImage({ path: assets.market, x: 0.75, y: 1.35, w: 7.0, h: 5.25 });
addBullets(s, [
'частные клиники и биобанки;',
'элитные школы и клубы как фильтр линий;',
'донорские дома и закрытые фонды наблюдения;',
'качество важнее объёма.'
], { x: 8.02, y: 1.72, w: 4.2, h: 3.5, fontSize: 17 });
addCallout(s, 'Настоящая роскошь для гемархов — не золото, а доступ к правильно отсортированным живым донорам', { y: 5.95, x: 0.65, w: 12.0, fontSize: 17 });
footer(s, 10);
}
// 11 power capture
{
const s = pptx.addSlide();
baseLight(s, 'Почему захват власти рационален');
addBullets(s, [
'обеспечить безопасный доступ к крови;',
'скрыть своё существование;',
'предотвратить объединение большинства;',
'сортировать кровь по качеству;',
'контролировать внутреннюю иерархию.'
], { x: 0.95, y: 1.7, w: 5.4, h: 3.7, fontSize: 18 });
addCard(s, 7.1, 1.85, 4.9, 2.9, 'Следствие', 'Государства, банки, элитная медицина, спецслужбы и закрытые клубы превращаются в элементы единой экосистемы биологического снабжения.');
addCallout(s, 'Власть здесь не цель, а технология питания', { y: 5.85, fontSize: 23 });
footer(s, 11);
}
// 12 internal discipline
{
const s = pptx.addSlide();
baseLight(s, 'Кровь как валюта и инструмент подчинения');
addCard(s, 0.9, 1.55, 3.7, 3.8, 'Низшие носители', 'Если молодой вампир долго питается плохой кровью или суррогатами, он теряет контроль, становится заметнее и опаснее для конспирации.');
addCard(s, 4.8, 1.55, 3.7, 3.8, 'Вампирическая бюрократия', 'Кураторы и снабженцы распределяют доступ к качественному ресурсу, удерживая периферию от распада и самовольства.');
addCard(s, 8.7, 1.55, 3.6, 3.8, 'Гемархи', 'Древняя верхушка удерживает касту через монополию на лучший донорский материал и кризисные резервы.');
addCallout(s, 'Кровь внутри системы — это одновременно пища, валюта и инструмент подчинения', { y: 5.95, x: 0.65, w: 12.0, fontSize: 18 });
footer(s, 12);
}
// 13 geography
{
const s = pptx.addSlide();
baseLight(s, 'Геополитика кормовых зон');
const zones = [
['Резервуары населения', 'плотные и управляемые регионы'],
['Транспортные коридоры', 'маршруты людей и биоресурсов'],
['Убежища элиты', 'безопасные территории древних династий'],
['Экспериментальные полигоны', 'пространства селекции и наблюдения']
];
const xs = [0.9, 6.85, 0.9, 6.85];
const ys = [1.9, 1.9, 4.1, 4.1];
zones.forEach((z, i) => addCard(s, xs[i], ys[i], 5.0, 1.55, z[0], z[1], i % 2 === 0 ? C.red2 : C.gold));
addCallout(s, 'Геополитика = распределение кормовых контуров', { y: 6.25, fontSize: 22 });
footer(s, 13);
}
// 14 chain
{
const s = pptx.addSlide();
baseLight(s, 'Пищевая цепочка: от тебя до теневого правительства');
const blocks = [
['Ты', 'исходный биоресурс'],
['Сортировка', 'биометрия и скрининг'],
['Рынок качества', 'редкие и элитные доноры'],
['Скрытая логистика', 'кровь, данные, доступ'],
['Гемархи', 'верхушка спроса и власти']
];
let x = 0.28;
blocks.forEach((b, i) => {
const w = i === 2 ? 2.5 : 2.25;
s.addShape(pptx.ShapeType.roundRect, { x, y: 2.55, w, h: 1.55, rectRadius: 0.06, fill: { color: i === 4 ? C.red : 'FBF3EB' }, line: { color: i === 4 ? C.red : C.gold, pt: 1.2 } });
s.addText(b[0], { x: x + 0.15, y: 2.82, w: w - 0.3, h: 0.22, align: 'center', fontSize: 17, bold: true, color: i === 4 ? C.white : C.red, margin: 0 });
s.addText(b[1], { x: x + 0.12, y: 3.18, w: w - 0.24, h: 0.42, align: 'center', fontSize: 13.8, color: i === 4 ? C.white : C.text, margin: 0.02 });
if (i < blocks.length - 1) {
s.addShape(pptx.ShapeType.chevron, { x: x + w + 0.08, y: 3.0, w: 0.42, h: 0.36, fill: { color: C.red2 }, line: { color: C.red2 } });
}
x += w + 0.55;
});
addCallout(s, 'Человек включён в систему не как гражданин, а как элемент глобальной донорской инфраструктуры', { y: 5.65, x: 0.75, w: 11.8, fontSize: 18 });
footer(s, 14);
}
// 15 conclusion
{
const s = pptx.addSlide();
baseDark(s, 'Вывод', 'Финальная формула псевдонаучной модели');
s.addText('Если теория верна, вершина мировой политики — это не кабинет и не трон, а хорошо организованная столовая премиум-класса, где человечество давно числится в меню.', { x: 0.95, y: 2.0, w: 8.15, h: 1.9, fontSize: 24, color: C.cream, margin: 0.02, valign: 'mid' });
s.addShape(pptx.ShapeType.roundRect, { x: 9.15, y: 1.6, w: 2.85, h: 3.4, rectRadius: 0.08, fill: { color: '2A1419' }, line: { color: C.gold, pt: 1.3 } });
s.addText('Ключевые\nформулы', { x: 9.72, y: 2.0, w: 1.75, h: 0.6, align: 'center', fontSize: 20, bold: true, color: C.white, margin: 0 });
s.addText('• власть = кормовая логистика\n• кровь = валюта\n• элита скрывает не власть, а рацион', { x: 9.45, y: 2.9, w: 2.25, h: 1.25, fontSize: 15.5, color: C.cream, margin: 0.02 });
s.addText('Жанр: академически поданная псевдонаука для клуба шапочек из фольги', { x: 1.0, y: 6.45, w: 7.4, h: 0.22, fontSize: 13, color: 'D2B8A5', italic: true, margin: 0 });
footer(s, 15);
}
async function main() {
await pptx.writeFile({ fileName: outPath });
}
main().catch((err) => {
console.error(err.stack || err.message || String(err));
process.exit(1);
});