diff --git a/assets/generated/01-title-food-chain.png b/assets/generated/01-title-food-chain.png new file mode 100644 index 0000000..92c5a4c Binary files /dev/null and b/assets/generated/01-title-food-chain.png differ diff --git a/assets/generated/02-medieval-origin.png b/assets/generated/02-medieval-origin.png new file mode 100644 index 0000000..8c95f08 Binary files /dev/null and b/assets/generated/02-medieval-origin.png differ diff --git a/assets/generated/03-vampire-classes.png b/assets/generated/03-vampire-classes.png new file mode 100644 index 0000000..03f06a7 Binary files /dev/null and b/assets/generated/03-vampire-classes.png differ diff --git a/assets/generated/04-failed-infection.png b/assets/generated/04-failed-infection.png new file mode 100644 index 0000000..fc2cea8 Binary files /dev/null and b/assets/generated/04-failed-infection.png differ diff --git a/assets/generated/05-recognize-vampire.png b/assets/generated/05-recognize-vampire.png new file mode 100644 index 0000000..5d07fb5 Binary files /dev/null and b/assets/generated/05-recognize-vampire.png differ diff --git a/assets/generated/06-blood-economy.png b/assets/generated/06-blood-economy.png new file mode 100644 index 0000000..6276d77 Binary files /dev/null and b/assets/generated/06-blood-economy.png differ diff --git a/assets/generated/07-artificial-blood.png b/assets/generated/07-artificial-blood.png new file mode 100644 index 0000000..c86be55 Binary files /dev/null and b/assets/generated/07-artificial-blood.png differ diff --git a/assets/generated/08-hidden-donor-market.png b/assets/generated/08-hidden-donor-market.png new file mode 100644 index 0000000..f279def Binary files /dev/null and b/assets/generated/08-hidden-donor-market.png differ diff --git a/assets/generated/09-donor-house.png b/assets/generated/09-donor-house.png new file mode 100644 index 0000000..15b7d94 Binary files /dev/null and b/assets/generated/09-donor-house.png differ diff --git a/assets/generated/10-blood-etiquette.png b/assets/generated/10-blood-etiquette.png new file mode 100644 index 0000000..aedfc8a Binary files /dev/null and b/assets/generated/10-blood-etiquette.png differ diff --git a/assets/generated/11-feeding-zones-map.png b/assets/generated/11-feeding-zones-map.png new file mode 100644 index 0000000..3b867c8 Binary files /dev/null and b/assets/generated/11-feeding-zones-map.png differ diff --git a/assets/generated/12-food-chain-chart.png b/assets/generated/12-food-chain-chart.png new file mode 100644 index 0000000..9815901 Binary files /dev/null and b/assets/generated/12-food-chain-chart.png differ diff --git a/assets/generated/README.md b/assets/generated/README.md new file mode 100644 index 0000000..fca7eb4 --- /dev/null +++ b/assets/generated/README.md @@ -0,0 +1,40 @@ +# Generated vampire visuals + +Подписанные версии лежат в SVG-файлах: плашка с текстом редактируется прямо в SVG. Чистые PNG лежат рядом с теми же номерами. + +- 01-title-food-chain + - PNG: `01-title-food-chain.png` + - Подпись: Титульная картинка — Вампирическая пищевая цепочка: элита, отбор и человечество как ресурс +- 02-medieval-origin + - PNG: `02-medieval-origin.png` + - Подпись: Происхождение вируса — XII-XIV века: войны, эпидемии и скрытое распространение SNV-12 +- 03-vampire-classes + - PNG: `03-vampire-classes.png` + - Подпись: Классы вампиров — Молодой носитель, старший адаптант и гемарх в одной иерархии +- 04-failed-infection + - PNG: `04-failed-infection.png` + - Подпись: Неудачное заражение — Феррогемный каскад и термогемолитический коллапс +- 05-recognize-vampire + - PNG: `05-recognize-vampire.png` + - Подпись: Как распознать вампира — Судебно-медицинский плакат с внешними и поведенческими маркерами +- 06-blood-economy + - PNG: `06-blood-economy.png` + - Подпись: Экономика качественной крови — Массовая, стабильная, пиковая и династическая кровь как ресурс +- 07-artificial-blood + - PNG: `07-artificial-blood.png` + - Подпись: Почему искусственная кровь не подходит — Сравнение живой сигнатуры крови и стерильного суррогата +- 08-hidden-donor-market + - PNG: `08-hidden-donor-market.png` + - Подпись: Тайный рынок доноров — Клиники, биобанки, школы, клубы и логистика к верхушке +- 09-donor-house + - PNG: `09-donor-house.png` + - Подпись: Донорский дом — Элитный пансион как скрытая инфраструктура премиальных доноров +- 10-blood-etiquette + - PNG: `10-blood-etiquette.png` + - Подпись: Кровяной этикет элиты — Аристократический ритуал оценки донора как дегустация вина +- 11-feeding-zones-map + - PNG: `11-feeding-zones-map.png` + - Подпись: Геополитика кормовых зон — Резервуары населения, коридоры, убежища и экспериментальные территории +- 12-food-chain-chart + - PNG: `12-food-chain-chart.png` + - Подпись: Пищевая цепочка — От человека через сортировку и рынок качества к гемархам diff --git a/generate_presentation.js b/generate_presentation.js index df2169b..7ff0d20 100644 --- a/generate_presentation.js +++ b/generate_presentation.js @@ -4,9 +4,18 @@ 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') + title: path.join(base, 'assets', 'generated', '01-title-food-chain.png'), + medieval: path.join(base, 'assets', 'generated', '02-medieval-origin.png'), + classes: path.join(base, 'assets', 'generated', '03-vampire-classes.png'), + failed: path.join(base, 'assets', 'generated', '04-failed-infection.png'), + recognize: path.join(base, 'assets', 'generated', '05-recognize-vampire.png'), + blood: path.join(base, 'assets', 'generated', '06-blood-economy.png'), + artificial: path.join(base, 'assets', 'generated', '07-artificial-blood.png'), + market: path.join(base, 'assets', 'generated', '08-hidden-donor-market.png'), + donorHouse: path.join(base, 'assets', 'generated', '09-donor-house.png'), + etiquette: path.join(base, 'assets', 'generated', '10-blood-etiquette.png'), + zones: path.join(base, 'assets', 'generated', '11-feeding-zones-map.png'), + chain: path.join(base, 'assets', 'generated', '12-food-chain-chart.png') }; const pptx = new pptxgen(); @@ -26,7 +35,6 @@ const C = { bgDark: '130B0D', bgLight: 'F4EEE7', card: 'FFF8F2', - card2: 'F7E9DD', red: '7A1623', red2: 'A42A37', text: '24181A', @@ -108,15 +116,12 @@ function addCard(slide, x, y, w, h, title, body, accent = C.red2) { { 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 }); + s.addImage({ path: assets.title, x: 0, y: 0, w: 13.333, h: 7.5 }); + s.addShape(pptx.ShapeType.rect, { x: 0, y: 0, w: 13.333, h: 7.5, fill: { color: '120A0D', transparency: 34 }, line: { color: '120A0D', transparency: 100 } }); + s.addShape(pptx.ShapeType.roundRect, { x: 0.72, y: 0.82, w: 6.95, h: 5.25, rectRadius: 0.06, fill: { color: '1B1114', transparency: 15 }, line: { color: C.red2, pt: 1.1, transparency: 20 } }); + s.addText('Пищевая цепочка:\nот тебя до теневого правительства', { x: 1.0, y: 1.15, w: 6.3, h: 1.5, color: C.white, fontFace: 'Aptos Display', fontSize: 25, bold: true, margin: 0 }); + s.addText('Расширенная версия: типы вампиров,\nкачественная кровь и скрытый рынок доноров', { x: 1.04, y: 2.95, w: 6.0, h: 0.75, color: C.cream, fontSize: 17.5, italic: true, margin: 0 }); + s.addText('Клуб шапочек из фольги\nПсевдонаучный доклад в академическом стиле', { x: 1.04, y: 4.0, w: 4.9, h: 0.8, color: 'E0D0C4', fontSize: 16, margin: 0 }); footer(s, 1); } @@ -154,180 +159,168 @@ function addCard(slide, x, y, w, h, title, body, accent = C.red2) { { 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 }); + s.addImage({ path: assets.medieval, x: 0.78, y: 1.28, w: 6.9, h: 4.85 }); + addBullets(s, [ + 'войны и миграции ускоряют перенос патогена;', + 'антисанитария скрывает аномальные случаи;', + 'массовая смертность маскирует новый фенотип;', + 'фольклор фиксирует ранние утечки в легенды.' + ], { x: 8.0, y: 1.7, w: 4.2, h: 3.7, fontSize: 17.5 }); + addCallout(s, 'Там, где высокая смертность, новый патоген легче принять за обычное бедствие', { y: 6.02, fontSize: 19 }); footer(s, 4); } -// 5 Classes with image +// 5 Classes { const s = pptx.addSlide(); baseLight(s, 'Классы вампирической адаптации'); - s.addImage({ path: assets.classes, x: 0.78, y: 1.35, w: 7.0, h: 5.35 }); + s.addImage({ path: assets.classes, x: 0.78, y: 1.35, w: 7.0, h: 5.1 }); addBullets(s, [ 'молодой носитель: нестабилен и голоден;', 'старший адаптант: устойчив и дисциплинирован;', - 'гемарх: древняя элита, пьёт редко, но требует лучшее.', - 'чем раньше возраст заражения, тем легче клеточная интеграция.' - ], { x: 8.02, y: 1.7, w: 4.4, h: 3.8, fontSize: 17 }); + 'гемарх: древняя элита, пьёт редко, но требует лучшее;', + 'ранний возраст заражения повышает шанс интеграции.' + ], { x: 8.02, y: 1.7, w: 4.25, h: 3.9, fontSize: 16.8 }); addCallout(s, 'Древность в этой системе — не возраст, а политический капитал', { y: 6.0, w: 12.0, x: 0.65, fontSize: 20 }); footer(s, 5); } -// 6 failed infection +// 6 Failed infection { const s = pptx.addSlide(); baseLight(s, 'Не всякий укушенный становится вампиром'); - addCard(s, 0.9, 1.55, 5.4, 3.85, 'Термогемолитический коллапс', 'У части заражённых SNV-12 запускает гиперсинтез термоактивных гемокатализаторов. При превышении критического порога включается феррогемный каскад: кровь перегревается, разрушается и даёт летальный исход, который фольклор описывает как «закипание крови».'); + s.addImage({ path: assets.failed, x: 0.78, y: 1.28, w: 6.9, h: 4.9 }); addBullets(s, [ - 'летальная несовместимость с вирусом;', - 'редкость успешной вампиризации;', - 'малочисленность касты объясняется биологически;', - 'выживают только совместимые организмы.' - ], { x: 7.0, y: 1.9, w: 4.8, h: 3.2, fontSize: 18 }); - addCallout(s, 'Не всякий укушенный становится вампиром; большинство становятся статистикой'); + 'феррогемный каскад запускает перегрев крови;', + 'летальная несовместимость отсеивает большинство;', + 'успешная вампиризация биологически редка;', + 'малочисленность касты имеет псевдонаучное объяснение.' + ], { x: 8.0, y: 1.72, w: 4.2, h: 3.8, fontSize: 17 }); + addCallout(s, 'Не всякий укушенный становится вампиром; большинство становятся статистикой', { y: 6.0, fontSize: 18.5 }); footer(s, 6); } -// 7 recognition +// 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 }); + s.addImage({ path: assets.recognize, x: 0.78, y: 1.28, w: 6.85, h: 4.95 }); + addBullets(s, [ + 'клыки чуть длиннее нормы;', + 'странно медленное старение;', + 'в голоде — тёмный расширенный зрачок;', + 'закрытые клубы и слишком долгая карьера.' + ], { x: 8.0, y: 1.7, w: 4.2, h: 3.6, fontSize: 17.3 }); + addCallout(s, 'Ни один симптом не доказывает ничего сам по себе — работает только совокупность', { y: 6.0, w: 12.0, x: 0.65, fontSize: 18.3 }); footer(s, 7); } -// 8 blood economy with image +// 8 Blood economy { const s = pptx.addSlide(); baseLight(s, 'Экономика качественной крови'); - s.addImage({ path: assets.blood, x: 0.78, y: 1.35, w: 7.1, h: 5.25 }); + s.addImage({ path: assets.blood, x: 0.78, y: 1.3, w: 7.0, h: 4.95 }); 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 }); + ], { x: 8.0, y: 1.65, w: 4.25, h: 3.8, fontSize: 16.9 }); + addCallout(s, 'Чем древнее вампир, тем реже он питается, но тем дороже обходится каждый акт питания', { y: 6.0, x: 0.65, w: 12.0, fontSize: 17.8 }); footer(s, 8); } -// 9 artificial blood +// 9 Artificial blood { const s = pptx.addSlide(); baseLight(s, 'Почему искусственная кровь им не подходит'); - addCard(s, 0.9, 1.55, 5.2, 3.95, 'Живая сигнатура', 'Для носителей SNV-12 важны не только клетки крови, но и краткоживущий нейроэндокринный профиль донора: гормоны, стрессовые маркеры, текущий метаболизм, «живая» биохимическая сигнатура.'); + s.addImage({ path: assets.artificial, x: 0.78, y: 1.28, w: 7.0, h: 4.95 }); addBullets(s, [ - 'искусственная кровь даёт базовую функцию;', - 'но не даёт истинного насыщения;', - 'не обеспечивает полную регенерацию;', - 'не восстанавливает фототолерантность у гемархов.' - ], { x: 7.0, y: 1.8, w: 4.9, h: 3.3, fontSize: 17.5 }); - addCallout(s, 'Искусственная кровь для них — суррогат, а не решение'); + 'живая кровь несёт гормоны и стрессовые маркеры;', + 'искусственный суррогат даёт только базовую функцию;', + 'у гемархов не возникает полноценного насыщения;', + 'фототолерантность и регенерация не восстанавливаются.' + ], { x: 8.0, y: 1.67, w: 4.25, h: 3.8, fontSize: 16.8 }); + addCallout(s, 'Искусственная кровь для них — суррогат, а не решение', { y: 6.0, fontSize: 19 }); footer(s, 9); } -// 10 donor market image +// 10 Donor market { const s = pptx.addSlide(); baseLight(s, 'Тайный рынок доноров'); - s.addImage({ path: assets.market, x: 0.75, y: 1.35, w: 7.0, h: 5.25 }); + s.addImage({ path: assets.market, x: 0.78, y: 1.28, w: 6.95, h: 4.95 }); 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 }); + addCallout(s, 'Настоящая роскошь для гемархов — не золото, а доступ к правильно отсортированным живым донорам', { y: 6.0, x: 0.65, w: 12.0, fontSize: 17 }); footer(s, 10); } -// 11 power capture +// 11 Power capture { const s = pptx.addSlide(); baseLight(s, 'Почему захват власти рационален'); + s.addImage({ path: assets.donorHouse, x: 0.78, y: 1.28, w: 6.95, h: 4.95 }); 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 }); + 'контролировать внутреннюю иерархию через снабжение.' + ], { x: 8.0, y: 1.72, w: 4.2, h: 3.7, fontSize: 17.2 }); + addCallout(s, 'Власть здесь не цель, а технология питания', { y: 6.0, fontSize: 22 }); footer(s, 11); } -// 12 internal discipline +// 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 }); + s.addImage({ path: assets.etiquette, x: 0.78, y: 1.28, w: 6.95, h: 4.95 }); + addBullets(s, [ + 'доступ к качественной крови = статус;', + 'плохое питание ломает самоконтроль низших носителей;', + 'снабжение превращается в механизм дисциплины;', + 'верхушка удерживает касту через монополию на лучший ресурс.' + ], { x: 8.0, y: 1.68, w: 4.2, h: 3.8, fontSize: 16.9 }); + addCallout(s, 'Кровь внутри системы — это одновременно пища, валюта и инструмент подчинения', { y: 6.0, x: 0.65, w: 12.0, fontSize: 18 }); footer(s, 12); } -// 13 geography +// 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 }); + s.addImage({ path: assets.zones, x: 0.78, y: 1.28, w: 7.0, h: 4.98 }); + addBullets(s, [ + 'резервуары населения;', + 'транспортные коридоры людей и биоресурсов;', + 'убежища древних династий;', + 'экспериментальные зоны селекции и наблюдения.' + ], { x: 8.0, y: 1.7, w: 4.2, h: 3.7, fontSize: 17.1 }); + addCallout(s, 'Геополитика = распределение кормовых контуров', { y: 6.02, fontSize: 21 }); footer(s, 13); } -// 14 chain +// 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 }); + s.addImage({ path: assets.chain, x: 0.78, y: 1.28, w: 7.0, h: 4.98 }); + addBullets(s, [ + 'человек — исходный биоресурс;', + 'системы учёта отсеивают пригодных доноров;', + 'рынок качества поднимает ресурс к верхушке;', + 'гемархи замыкают всю логистику на себе.' + ], { x: 8.0, y: 1.72, w: 4.2, h: 3.7, fontSize: 17.1 }); + addCallout(s, 'Человек включён в систему не как гражданин, а как элемент глобальной донорской инфраструктуры', { y: 6.0, x: 0.65, w: 12.0, fontSize: 17.6 }); footer(s, 14); } -// 15 conclusion +// 15 Conclusion { const s = pptx.addSlide(); baseDark(s, 'Вывод', 'Финальная формула псевдонаучной модели'); diff --git a/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pdf b/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pdf index 34d73e9..5e4b2ac 100644 Binary files a/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pdf and b/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pdf differ diff --git a/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pptx b/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pptx index 461ab1d..6964661 100644 Binary files a/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pptx and b/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pptx differ diff --git a/rendered_check/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.png b/rendered_check/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.png index c9ec97c..b86af45 100644 Binary files a/rendered_check/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.png and b/rendered_check/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.png differ