claude-presentation-master 7.2.1 → 7.4.0
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/dist/index.d.mts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +191 -60
- package/dist/index.mjs +191 -60
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -354,6 +354,8 @@ interface ContentAnalysis$1 {
|
|
|
354
354
|
detectedType: PresentationType$1;
|
|
355
355
|
/** Main title */
|
|
356
356
|
title: string;
|
|
357
|
+
/** Subtitle (line after title) */
|
|
358
|
+
subtitle?: string;
|
|
357
359
|
/** Content sections */
|
|
358
360
|
sections: ContentSection$1[];
|
|
359
361
|
/** SCQA structure extracted */
|
|
@@ -950,6 +952,7 @@ interface ContentSection {
|
|
|
950
952
|
interface ContentAnalysis {
|
|
951
953
|
detectedType: PresentationType;
|
|
952
954
|
title: string;
|
|
955
|
+
subtitle: string;
|
|
953
956
|
sections: ContentSection[];
|
|
954
957
|
keyMessages: string[];
|
|
955
958
|
dataPoints: Array<{
|
|
@@ -990,7 +993,12 @@ declare class ContentAnalyzer {
|
|
|
990
993
|
*/
|
|
991
994
|
private parseContent;
|
|
992
995
|
/**
|
|
993
|
-
* Extract the main title from content
|
|
996
|
+
* Extract the main title AND subtitle from content
|
|
997
|
+
* Subtitle is the line immediately after the H1 title (if not another header)
|
|
998
|
+
*/
|
|
999
|
+
private extractTitleAndSubtitle;
|
|
1000
|
+
/**
|
|
1001
|
+
* Extract the main title from content (legacy wrapper)
|
|
994
1002
|
*/
|
|
995
1003
|
private extractTitle;
|
|
996
1004
|
/**
|
|
@@ -1215,6 +1223,11 @@ declare class ContentPatternClassifier {
|
|
|
1215
1223
|
} | null;
|
|
1216
1224
|
/**
|
|
1217
1225
|
* Extract timeline/process steps from content
|
|
1226
|
+
* Handles multiple formats:
|
|
1227
|
+
* - "Step 1: Do something" → label: "Step 1", description: "Do something"
|
|
1228
|
+
* - "1. First item" → label: "1", description: "First item"
|
|
1229
|
+
* - "Title - Description text" → label: "Title", description: "Description text"
|
|
1230
|
+
* - "Plain text" → label: "1", description: "Plain text"
|
|
1218
1231
|
*/
|
|
1219
1232
|
extractSteps(section: ContentSection$1): Array<{
|
|
1220
1233
|
label: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -354,6 +354,8 @@ interface ContentAnalysis$1 {
|
|
|
354
354
|
detectedType: PresentationType$1;
|
|
355
355
|
/** Main title */
|
|
356
356
|
title: string;
|
|
357
|
+
/** Subtitle (line after title) */
|
|
358
|
+
subtitle?: string;
|
|
357
359
|
/** Content sections */
|
|
358
360
|
sections: ContentSection$1[];
|
|
359
361
|
/** SCQA structure extracted */
|
|
@@ -950,6 +952,7 @@ interface ContentSection {
|
|
|
950
952
|
interface ContentAnalysis {
|
|
951
953
|
detectedType: PresentationType;
|
|
952
954
|
title: string;
|
|
955
|
+
subtitle: string;
|
|
953
956
|
sections: ContentSection[];
|
|
954
957
|
keyMessages: string[];
|
|
955
958
|
dataPoints: Array<{
|
|
@@ -990,7 +993,12 @@ declare class ContentAnalyzer {
|
|
|
990
993
|
*/
|
|
991
994
|
private parseContent;
|
|
992
995
|
/**
|
|
993
|
-
* Extract the main title from content
|
|
996
|
+
* Extract the main title AND subtitle from content
|
|
997
|
+
* Subtitle is the line immediately after the H1 title (if not another header)
|
|
998
|
+
*/
|
|
999
|
+
private extractTitleAndSubtitle;
|
|
1000
|
+
/**
|
|
1001
|
+
* Extract the main title from content (legacy wrapper)
|
|
994
1002
|
*/
|
|
995
1003
|
private extractTitle;
|
|
996
1004
|
/**
|
|
@@ -1215,6 +1223,11 @@ declare class ContentPatternClassifier {
|
|
|
1215
1223
|
} | null;
|
|
1216
1224
|
/**
|
|
1217
1225
|
* Extract timeline/process steps from content
|
|
1226
|
+
* Handles multiple formats:
|
|
1227
|
+
* - "Step 1: Do something" → label: "Step 1", description: "Do something"
|
|
1228
|
+
* - "1. First item" → label: "1", description: "First item"
|
|
1229
|
+
* - "Title - Description text" → label: "Title", description: "Description text"
|
|
1230
|
+
* - "Plain text" → label: "1", description: "Plain text"
|
|
1218
1231
|
*/
|
|
1219
1232
|
extractSteps(section: ContentSection$1): Array<{
|
|
1220
1233
|
label: string;
|
package/dist/index.js
CHANGED
|
@@ -961,7 +961,8 @@ var ContentAnalyzer = class {
|
|
|
961
961
|
async analyze(content, contentType) {
|
|
962
962
|
await this.initialize();
|
|
963
963
|
const text = this.parseContent(content, contentType);
|
|
964
|
-
const title = this.
|
|
964
|
+
const { title, subtitle } = this.extractTitleAndSubtitle(text);
|
|
965
|
+
logger.step(`Title: "${title}", Subtitle: "${subtitle || "(none)"}"`);
|
|
965
966
|
const detectedType = this.detectPresentationType(text);
|
|
966
967
|
logger.step(`Detected type: ${detectedType}`);
|
|
967
968
|
const sections = this.extractSections(text);
|
|
@@ -974,9 +975,13 @@ var ContentAnalyzer = class {
|
|
|
974
975
|
const titles = sections.map((s) => s.header).filter((h) => h.length > 0);
|
|
975
976
|
const starMoments = this.extractStarMoments(text);
|
|
976
977
|
const estimatedSlideCount = Math.max(5, sections.length + 3);
|
|
978
|
+
const whatIsContent = scqa.situation ? [scqa.situation] : [];
|
|
979
|
+
const whatCouldBeContent = scqa.answer ? [scqa.answer] : keyMessages.slice(0, 2);
|
|
977
980
|
return {
|
|
978
981
|
detectedType,
|
|
979
982
|
title,
|
|
983
|
+
subtitle,
|
|
984
|
+
// NEW: Use explicit subtitle from content
|
|
980
985
|
sections,
|
|
981
986
|
keyMessages,
|
|
982
987
|
dataPoints,
|
|
@@ -987,8 +992,10 @@ var ContentAnalyzer = class {
|
|
|
987
992
|
answer: scqa.answer || ""
|
|
988
993
|
},
|
|
989
994
|
sparkline: {
|
|
990
|
-
whatIs:
|
|
991
|
-
|
|
995
|
+
whatIs: whatIsContent,
|
|
996
|
+
// FIX: Use situation, not CTA
|
|
997
|
+
whatCouldBe: whatCouldBeContent,
|
|
998
|
+
// FIX: Use answer/vision, not random messages
|
|
992
999
|
callToAdventure: sparkline.callToAction || ""
|
|
993
1000
|
},
|
|
994
1001
|
titles,
|
|
@@ -1016,18 +1023,46 @@ var ContentAnalyzer = class {
|
|
|
1016
1023
|
return text;
|
|
1017
1024
|
}
|
|
1018
1025
|
/**
|
|
1019
|
-
* Extract the main title from content
|
|
1026
|
+
* Extract the main title AND subtitle from content
|
|
1027
|
+
* Subtitle is the line immediately after the H1 title (if not another header)
|
|
1020
1028
|
*/
|
|
1021
|
-
|
|
1022
|
-
const
|
|
1023
|
-
|
|
1024
|
-
|
|
1029
|
+
extractTitleAndSubtitle(text) {
|
|
1030
|
+
const lines = text.split("\n");
|
|
1031
|
+
let title = "Presentation";
|
|
1032
|
+
let subtitle = "";
|
|
1033
|
+
let foundTitle = false;
|
|
1034
|
+
let titleLineIndex = -1;
|
|
1035
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1036
|
+
const rawLine = lines[i];
|
|
1037
|
+
if (!rawLine) continue;
|
|
1038
|
+
const line = rawLine.trim();
|
|
1039
|
+
const h1Match = line.match(/^#\s+(.+)$/);
|
|
1040
|
+
if (h1Match && h1Match[1] && !foundTitle) {
|
|
1041
|
+
title = h1Match[1].replace(/\*\*/g, "").trim();
|
|
1042
|
+
foundTitle = true;
|
|
1043
|
+
titleLineIndex = i;
|
|
1044
|
+
continue;
|
|
1045
|
+
}
|
|
1046
|
+
if (foundTitle && i > titleLineIndex && line.length > 0) {
|
|
1047
|
+
if (line.startsWith("#")) break;
|
|
1048
|
+
if (line.startsWith("-") || line.startsWith("*") || /^\d+\./.test(line)) break;
|
|
1049
|
+
subtitle = line.replace(/\*\*/g, "").trim().slice(0, 100);
|
|
1050
|
+
break;
|
|
1051
|
+
}
|
|
1025
1052
|
}
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1053
|
+
if (!foundTitle) {
|
|
1054
|
+
const firstLine = lines.find((l) => l.trim().length > 0);
|
|
1055
|
+
if (firstLine) {
|
|
1056
|
+
title = firstLine.replace(/^#+\s*/, "").replace(/\*\*/g, "").trim().slice(0, 80);
|
|
1057
|
+
}
|
|
1029
1058
|
}
|
|
1030
|
-
return
|
|
1059
|
+
return { title, subtitle };
|
|
1060
|
+
}
|
|
1061
|
+
/**
|
|
1062
|
+
* Extract the main title from content (legacy wrapper)
|
|
1063
|
+
*/
|
|
1064
|
+
extractTitle(text) {
|
|
1065
|
+
return this.extractTitleAndSubtitle(text).title;
|
|
1031
1066
|
}
|
|
1032
1067
|
/**
|
|
1033
1068
|
* Detect presentation type from content signals
|
|
@@ -1650,6 +1685,11 @@ var ContentPatternClassifier = class {
|
|
|
1650
1685
|
}
|
|
1651
1686
|
/**
|
|
1652
1687
|
* Extract timeline/process steps from content
|
|
1688
|
+
* Handles multiple formats:
|
|
1689
|
+
* - "Step 1: Do something" → label: "Step 1", description: "Do something"
|
|
1690
|
+
* - "1. First item" → label: "1", description: "First item"
|
|
1691
|
+
* - "Title - Description text" → label: "Title", description: "Description text"
|
|
1692
|
+
* - "Plain text" → label: "1", description: "Plain text"
|
|
1653
1693
|
*/
|
|
1654
1694
|
extractSteps(section) {
|
|
1655
1695
|
const steps = [];
|
|
@@ -1660,12 +1700,28 @@ var ContentPatternClassifier = class {
|
|
|
1660
1700
|
label: stepMatch[1].trim(),
|
|
1661
1701
|
description: stepMatch[2].trim()
|
|
1662
1702
|
});
|
|
1663
|
-
|
|
1703
|
+
continue;
|
|
1704
|
+
}
|
|
1705
|
+
const dashMatch = bullet.match(/^([^-]+)\s+-\s+(.+)$/);
|
|
1706
|
+
if (dashMatch && dashMatch[1] && dashMatch[2]) {
|
|
1664
1707
|
steps.push({
|
|
1665
|
-
label:
|
|
1666
|
-
description:
|
|
1708
|
+
label: dashMatch[1].trim(),
|
|
1709
|
+
description: dashMatch[2].trim()
|
|
1667
1710
|
});
|
|
1711
|
+
continue;
|
|
1668
1712
|
}
|
|
1713
|
+
const colonMatch = bullet.match(/^([^:]+):\s*(.+)$/);
|
|
1714
|
+
if (colonMatch && colonMatch[1] && colonMatch[2] && colonMatch[1].length < 40) {
|
|
1715
|
+
steps.push({
|
|
1716
|
+
label: colonMatch[1].trim(),
|
|
1717
|
+
description: colonMatch[2].trim()
|
|
1718
|
+
});
|
|
1719
|
+
continue;
|
|
1720
|
+
}
|
|
1721
|
+
steps.push({
|
|
1722
|
+
label: `${steps.length + 1}`,
|
|
1723
|
+
description: bullet
|
|
1724
|
+
});
|
|
1669
1725
|
}
|
|
1670
1726
|
return steps;
|
|
1671
1727
|
}
|
|
@@ -1830,9 +1886,10 @@ var SlideFactory = class {
|
|
|
1830
1886
|
const data = {
|
|
1831
1887
|
title: this.truncateText(analysis.title, this.config.rules.wordsPerSlide.max)
|
|
1832
1888
|
};
|
|
1833
|
-
|
|
1889
|
+
const subtitleSource = analysis.subtitle || analysis.keyMessages[0] || "";
|
|
1890
|
+
if (subtitleSource) {
|
|
1834
1891
|
data.subtitle = this.truncateText(
|
|
1835
|
-
|
|
1892
|
+
subtitleSource,
|
|
1836
1893
|
this.config.defaults.subtitle.maxWords
|
|
1837
1894
|
// FROM KB
|
|
1838
1895
|
);
|
|
@@ -1876,7 +1933,9 @@ var SlideFactory = class {
|
|
|
1876
1933
|
addSCQASlides(slides, analysis) {
|
|
1877
1934
|
const scqa = analysis.scqa;
|
|
1878
1935
|
const titles = this.config.scqaTitles;
|
|
1879
|
-
|
|
1936
|
+
const minBodyLength = 20;
|
|
1937
|
+
const situationBody = scqa?.situation ? this.truncateText(scqa.situation, this.config.rules.wordsPerSlide.max) : "";
|
|
1938
|
+
if (situationBody.length >= minBodyLength && !this.usedContent.has("scqa-situation")) {
|
|
1880
1939
|
this.usedContent.add("scqa-situation");
|
|
1881
1940
|
slides.push({
|
|
1882
1941
|
index: slides.length,
|
|
@@ -1884,12 +1943,13 @@ var SlideFactory = class {
|
|
|
1884
1943
|
data: {
|
|
1885
1944
|
title: titles.situation,
|
|
1886
1945
|
// FROM KB - not hardcoded 'Current Situation'
|
|
1887
|
-
body:
|
|
1946
|
+
body: situationBody
|
|
1888
1947
|
},
|
|
1889
1948
|
classes: ["situation-slide"]
|
|
1890
1949
|
});
|
|
1891
1950
|
}
|
|
1892
|
-
|
|
1951
|
+
const complicationBody = scqa?.complication ? this.truncateText(scqa.complication, this.config.rules.wordsPerSlide.max) : "";
|
|
1952
|
+
if (complicationBody.length >= minBodyLength && !this.usedContent.has("scqa-complication")) {
|
|
1893
1953
|
this.usedContent.add("scqa-complication");
|
|
1894
1954
|
slides.push({
|
|
1895
1955
|
index: slides.length,
|
|
@@ -1897,12 +1957,13 @@ var SlideFactory = class {
|
|
|
1897
1957
|
data: {
|
|
1898
1958
|
title: titles.complication,
|
|
1899
1959
|
// FROM KB - not hardcoded 'The Challenge'
|
|
1900
|
-
body:
|
|
1960
|
+
body: complicationBody
|
|
1901
1961
|
},
|
|
1902
1962
|
classes: ["complication-slide"]
|
|
1903
1963
|
});
|
|
1904
1964
|
}
|
|
1905
|
-
|
|
1965
|
+
const questionBody = scqa?.question ? this.truncateText(scqa.question, this.config.rules.wordsPerSlide.max) : "";
|
|
1966
|
+
if (questionBody.length >= minBodyLength && !this.usedContent.has("scqa-question")) {
|
|
1906
1967
|
this.usedContent.add("scqa-question");
|
|
1907
1968
|
slides.push({
|
|
1908
1969
|
index: slides.length,
|
|
@@ -1910,7 +1971,7 @@ var SlideFactory = class {
|
|
|
1910
1971
|
data: {
|
|
1911
1972
|
title: titles.question,
|
|
1912
1973
|
// FROM KB - not hardcoded 'The Question'
|
|
1913
|
-
body:
|
|
1974
|
+
body: questionBody
|
|
1914
1975
|
},
|
|
1915
1976
|
classes: ["question-slide"]
|
|
1916
1977
|
});
|
|
@@ -1920,7 +1981,8 @@ var SlideFactory = class {
|
|
|
1920
1981
|
const spark = analysis.sparkline;
|
|
1921
1982
|
const titles = this.config.sparklineTitles;
|
|
1922
1983
|
const whatIsFirst = spark?.whatIs?.[0];
|
|
1923
|
-
|
|
1984
|
+
const whatIsBody = whatIsFirst ? this.truncateText(whatIsFirst, this.config.rules.wordsPerSlide.max) : "";
|
|
1985
|
+
if (whatIsBody.length >= 20 && !this.usedContent.has("spark-what-is")) {
|
|
1924
1986
|
this.usedContent.add("spark-what-is");
|
|
1925
1987
|
slides.push({
|
|
1926
1988
|
index: slides.length,
|
|
@@ -1928,13 +1990,14 @@ var SlideFactory = class {
|
|
|
1928
1990
|
data: {
|
|
1929
1991
|
title: titles.whatIs,
|
|
1930
1992
|
// FROM KB - not hardcoded 'Where We Are Today'
|
|
1931
|
-
body:
|
|
1993
|
+
body: whatIsBody
|
|
1932
1994
|
},
|
|
1933
1995
|
classes: ["what-is-slide"]
|
|
1934
1996
|
});
|
|
1935
1997
|
}
|
|
1936
1998
|
const whatCouldBeFirst = spark?.whatCouldBe?.[0];
|
|
1937
|
-
|
|
1999
|
+
const whatCouldBeBody = whatCouldBeFirst ? this.truncateText(whatCouldBeFirst, this.config.rules.wordsPerSlide.max) : "";
|
|
2000
|
+
if (whatCouldBeBody.length >= 20 && !this.usedContent.has("spark-could-be")) {
|
|
1938
2001
|
this.usedContent.add("spark-could-be");
|
|
1939
2002
|
slides.push({
|
|
1940
2003
|
index: slides.length,
|
|
@@ -1942,7 +2005,7 @@ var SlideFactory = class {
|
|
|
1942
2005
|
data: {
|
|
1943
2006
|
title: titles.whatCouldBe,
|
|
1944
2007
|
// FROM KB - not hardcoded 'What Could Be'
|
|
1945
|
-
body:
|
|
2008
|
+
body: whatCouldBeBody
|
|
1946
2009
|
},
|
|
1947
2010
|
classes: ["what-could-be-slide"]
|
|
1948
2011
|
});
|
|
@@ -2151,16 +2214,18 @@ var SlideFactory = class {
|
|
|
2151
2214
|
};
|
|
2152
2215
|
}
|
|
2153
2216
|
createSingleStatementSlide(index, section) {
|
|
2217
|
+
const bodyContent = section.content || section.bullets.join(" ") || "";
|
|
2218
|
+
const truncatedBody = this.truncateText(bodyContent, this.config.rules.wordsPerSlide.max);
|
|
2219
|
+
if (truncatedBody.length < 15 && section.bullets.length > 0) {
|
|
2220
|
+
return this.createBulletSlide(index, section);
|
|
2221
|
+
}
|
|
2154
2222
|
return {
|
|
2155
2223
|
index,
|
|
2156
2224
|
type: "single-statement",
|
|
2157
2225
|
data: {
|
|
2158
2226
|
title: this.createTitle(section.header, section),
|
|
2159
|
-
body:
|
|
2160
|
-
|
|
2161
|
-
this.config.rules.wordsPerSlide.max
|
|
2162
|
-
// FROM KB
|
|
2163
|
-
)
|
|
2227
|
+
body: truncatedBody || section.header
|
|
2228
|
+
// Fallback to header if no body
|
|
2164
2229
|
},
|
|
2165
2230
|
classes: ["single-statement-slide"]
|
|
2166
2231
|
};
|
|
@@ -2534,6 +2599,9 @@ var TemplateEngine = class {
|
|
|
2534
2599
|
this.handlebars.registerHelper("animDelay", function(index, baseMs = 100) {
|
|
2535
2600
|
return `animation-delay: ${index * baseMs}ms`;
|
|
2536
2601
|
});
|
|
2602
|
+
this.handlebars.registerHelper("add", function(a, b) {
|
|
2603
|
+
return a + b;
|
|
2604
|
+
});
|
|
2537
2605
|
this.handlebars.registerHelper("safeHTML", function(text) {
|
|
2538
2606
|
return new import_handlebars.default.SafeString(text);
|
|
2539
2607
|
});
|
|
@@ -2641,7 +2709,12 @@ var TemplateEngine = class {
|
|
|
2641
2709
|
this.templates.set("single-statement", this.handlebars.compile(`
|
|
2642
2710
|
<section class="{{classes}}" data-slide-index="{{slideIndex}}" style="{{styles}}">
|
|
2643
2711
|
<div class="slide-content statement-content">
|
|
2712
|
+
{{#if body}}
|
|
2713
|
+
<h2 class="title animate-fadeIn">{{title}}</h2>
|
|
2714
|
+
<p class="statement animate-fadeIn delay-200">{{markdown body}}</p>
|
|
2715
|
+
{{else}}
|
|
2644
2716
|
<p class="statement animate-fadeIn">{{title}}</p>
|
|
2717
|
+
{{/if}}
|
|
2645
2718
|
</div>
|
|
2646
2719
|
{{> speakerNotes}}
|
|
2647
2720
|
</section>
|
|
@@ -2707,14 +2780,30 @@ var TemplateEngine = class {
|
|
|
2707
2780
|
<h2 class="title animate-fadeIn">{{title}}</h2>
|
|
2708
2781
|
<div class="columns two-columns">
|
|
2709
2782
|
<div class="column column-left animate-slideRight">
|
|
2710
|
-
{{#if
|
|
2711
|
-
|
|
2783
|
+
{{#if leftColumn.title}}<h3>{{leftColumn.title}}</h3>{{/if}}
|
|
2784
|
+
{{#if leftColumn.body}}
|
|
2785
|
+
<p class="body">{{markdown leftColumn.body}}</p>
|
|
2712
2786
|
{{/if}}
|
|
2713
|
-
{{#if
|
|
2714
|
-
|
|
2787
|
+
{{#if leftColumn.bullets}}
|
|
2788
|
+
<ul class="bullets stagger-children">
|
|
2789
|
+
{{#each leftColumn.bullets}}
|
|
2790
|
+
<li class="bullet animate-fadeIn" style="{{animDelay @index 150}}">{{markdown this}}</li>
|
|
2791
|
+
{{/each}}
|
|
2792
|
+
</ul>
|
|
2715
2793
|
{{/if}}
|
|
2716
2794
|
</div>
|
|
2717
2795
|
<div class="column column-right animate-slideLeft delay-200">
|
|
2796
|
+
{{#if rightColumn.title}}<h3>{{rightColumn.title}}</h3>{{/if}}
|
|
2797
|
+
{{#if rightColumn.body}}
|
|
2798
|
+
<p class="body">{{markdown rightColumn.body}}</p>
|
|
2799
|
+
{{/if}}
|
|
2800
|
+
{{#if rightColumn.bullets}}
|
|
2801
|
+
<ul class="bullets stagger-children">
|
|
2802
|
+
{{#each rightColumn.bullets}}
|
|
2803
|
+
<li class="bullet animate-fadeIn" style="{{animDelay @index 150}}">{{markdown this}}</li>
|
|
2804
|
+
{{/each}}
|
|
2805
|
+
</ul>
|
|
2806
|
+
{{/if}}
|
|
2718
2807
|
{{#if hasImage}}
|
|
2719
2808
|
{{> imageWithCaption images.[0]}}
|
|
2720
2809
|
{{else if metrics}}
|
|
@@ -2735,11 +2824,13 @@ var TemplateEngine = class {
|
|
|
2735
2824
|
{{#each columns}}
|
|
2736
2825
|
<div class="column animate-fadeIn" style="{{animDelay @index 200}}">
|
|
2737
2826
|
{{#if title}}<h3 class="column-title">{{title}}</h3>{{/if}}
|
|
2827
|
+
{{#if content}}<p class="column-body">{{markdown content}}</p>{{/if}}
|
|
2738
2828
|
{{#if body}}<p class="column-body">{{markdown body}}</p>{{/if}}
|
|
2739
2829
|
{{#if icon}}<div class="column-icon">{{icon}}</div>{{/if}}
|
|
2740
2830
|
</div>
|
|
2741
2831
|
{{/each}}
|
|
2742
2832
|
</div>
|
|
2833
|
+
{{> source}}
|
|
2743
2834
|
</div>
|
|
2744
2835
|
{{> speakerNotes}}
|
|
2745
2836
|
</section>
|
|
@@ -2748,25 +2839,24 @@ var TemplateEngine = class {
|
|
|
2748
2839
|
<section class="{{classes}}" data-slide-index="{{slideIndex}}" style="{{styles}}">
|
|
2749
2840
|
<div class="slide-content">
|
|
2750
2841
|
<h2 class="title animate-fadeIn">{{title}}</h2>
|
|
2751
|
-
<div class="comparison-container">
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
<
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
</div>
|
|
2760
|
-
<div class="comparison-divider"></div>
|
|
2761
|
-
<div class="comparison-right animate-slideLeft delay-200">
|
|
2762
|
-
<h3>{{rightTitle}}</h3>
|
|
2842
|
+
<div class="comparison-container columns two-columns">
|
|
2843
|
+
{{#each columns}}
|
|
2844
|
+
<div class="column comparison-{{#if @first}}left animate-slideRight{{else}}right animate-slideLeft delay-200{{/if}}">
|
|
2845
|
+
<h3 class="column-title">{{title}}</h3>
|
|
2846
|
+
{{#if content}}
|
|
2847
|
+
<p class="column-content">{{markdown content}}</p>
|
|
2848
|
+
{{/if}}
|
|
2849
|
+
{{#if bullets}}
|
|
2763
2850
|
<ul>
|
|
2764
|
-
{{#each
|
|
2851
|
+
{{#each bullets}}
|
|
2765
2852
|
<li>{{this}}</li>
|
|
2766
2853
|
{{/each}}
|
|
2767
2854
|
</ul>
|
|
2855
|
+
{{/if}}
|
|
2768
2856
|
</div>
|
|
2857
|
+
{{/each}}
|
|
2769
2858
|
</div>
|
|
2859
|
+
{{> source}}
|
|
2770
2860
|
</div>
|
|
2771
2861
|
{{> speakerNotes}}
|
|
2772
2862
|
</section>
|
|
@@ -2830,18 +2920,18 @@ var TemplateEngine = class {
|
|
|
2830
2920
|
<section class="{{classes}}" data-slide-index="{{slideIndex}}" style="{{styles}}">
|
|
2831
2921
|
<div class="slide-content">
|
|
2832
2922
|
<h2 class="title animate-fadeIn">{{title}}</h2>
|
|
2833
|
-
<div class="timeline stagger-children">
|
|
2834
|
-
{{#each
|
|
2835
|
-
<div class="timeline-item animate-fadeIn" style="{{animDelay @index 200}}">
|
|
2836
|
-
<div class="
|
|
2923
|
+
<div class="timeline steps stagger-children">
|
|
2924
|
+
{{#each steps}}
|
|
2925
|
+
<div class="step timeline-item animate-fadeIn" style="{{animDelay @index 200}}">
|
|
2926
|
+
<div class="step-number">{{add @index 1}}</div>
|
|
2837
2927
|
<div class="timeline-content">
|
|
2838
|
-
<div class="
|
|
2839
|
-
<div class="
|
|
2840
|
-
{{#if description}}<div class="timeline-desc">{{description}}</div>{{/if}}
|
|
2928
|
+
<div class="step-title">{{label}}</div>
|
|
2929
|
+
{{#if description}}<div class="step-desc">{{description}}</div>{{/if}}
|
|
2841
2930
|
</div>
|
|
2842
2931
|
</div>
|
|
2843
2932
|
{{/each}}
|
|
2844
2933
|
</div>
|
|
2934
|
+
{{> source}}
|
|
2845
2935
|
</div>
|
|
2846
2936
|
{{> speakerNotes}}
|
|
2847
2937
|
</section>
|
|
@@ -5379,29 +5469,70 @@ ${slides}
|
|
|
5379
5469
|
}
|
|
5380
5470
|
|
|
5381
5471
|
/* Comparison slides: Split visual */
|
|
5382
|
-
.reveal .slide-comparison .columns
|
|
5472
|
+
.reveal .slide-comparison .columns,
|
|
5473
|
+
.reveal .slide-comparison .comparison-container {
|
|
5383
5474
|
gap: 60px;
|
|
5384
5475
|
}
|
|
5385
|
-
.reveal .slide-comparison .column:first-child
|
|
5476
|
+
.reveal .slide-comparison .column:first-child,
|
|
5477
|
+
.reveal .slide-comparison .comparison-left {
|
|
5386
5478
|
border-right: 2px solid ${this.lightenColor(secondary, 70)};
|
|
5387
5479
|
padding-right: 30px;
|
|
5388
5480
|
}
|
|
5481
|
+
.reveal .column-title {
|
|
5482
|
+
font-size: 1.2em;
|
|
5483
|
+
font-weight: 600;
|
|
5484
|
+
margin-bottom: 0.5em;
|
|
5485
|
+
color: var(--color-accent);
|
|
5486
|
+
}
|
|
5487
|
+
.reveal .column-content,
|
|
5488
|
+
.reveal .column-body {
|
|
5489
|
+
line-height: 1.6;
|
|
5490
|
+
}
|
|
5389
5491
|
|
|
5390
5492
|
/* Timeline/Process: Visual flow */
|
|
5391
5493
|
.reveal .slide-timeline .steps,
|
|
5392
|
-
.reveal .slide-
|
|
5494
|
+
.reveal .slide-timeline .timeline,
|
|
5495
|
+
.reveal .slide-process .steps,
|
|
5496
|
+
.reveal .slide-process .process-steps {
|
|
5393
5497
|
display: flex;
|
|
5394
5498
|
gap: 20px;
|
|
5499
|
+
flex-wrap: wrap;
|
|
5500
|
+
justify-content: center;
|
|
5395
5501
|
}
|
|
5396
5502
|
.reveal .slide-timeline .step,
|
|
5397
|
-
.reveal .slide-
|
|
5503
|
+
.reveal .slide-timeline .timeline-item,
|
|
5504
|
+
.reveal .slide-process .step,
|
|
5505
|
+
.reveal .slide-process .process-step {
|
|
5398
5506
|
flex: 1;
|
|
5507
|
+
min-width: 150px;
|
|
5508
|
+
max-width: 250px;
|
|
5399
5509
|
padding: 20px;
|
|
5400
5510
|
background: ${isDark ? this.lightenColor(background, 10) : this.lightenColor(secondary, 92)};
|
|
5401
5511
|
border-radius: 8px;
|
|
5402
5512
|
border-top: 4px solid var(--color-accent);
|
|
5403
5513
|
${isDark ? `color: ${text};` : ""}
|
|
5404
5514
|
}
|
|
5515
|
+
.reveal .step-number {
|
|
5516
|
+
font-size: 1.5em;
|
|
5517
|
+
font-weight: 700;
|
|
5518
|
+
color: var(--color-accent);
|
|
5519
|
+
margin-bottom: 0.5em;
|
|
5520
|
+
}
|
|
5521
|
+
.reveal .step-title {
|
|
5522
|
+
font-size: 1.1em;
|
|
5523
|
+
font-weight: 600;
|
|
5524
|
+
margin-bottom: 0.5em;
|
|
5525
|
+
}
|
|
5526
|
+
.reveal .step-desc {
|
|
5527
|
+
font-size: 0.9em;
|
|
5528
|
+
color: var(--color-text-light);
|
|
5529
|
+
}
|
|
5530
|
+
.reveal .step-arrow {
|
|
5531
|
+
display: flex;
|
|
5532
|
+
align-items: center;
|
|
5533
|
+
font-size: 1.5em;
|
|
5534
|
+
color: var(--color-accent);
|
|
5535
|
+
}
|
|
5405
5536
|
|
|
5406
5537
|
/* Progress bar enhancement */
|
|
5407
5538
|
.reveal .progress {
|
package/dist/index.mjs
CHANGED
|
@@ -889,7 +889,8 @@ var ContentAnalyzer = class {
|
|
|
889
889
|
async analyze(content, contentType) {
|
|
890
890
|
await this.initialize();
|
|
891
891
|
const text = this.parseContent(content, contentType);
|
|
892
|
-
const title = this.
|
|
892
|
+
const { title, subtitle } = this.extractTitleAndSubtitle(text);
|
|
893
|
+
logger.step(`Title: "${title}", Subtitle: "${subtitle || "(none)"}"`);
|
|
893
894
|
const detectedType = this.detectPresentationType(text);
|
|
894
895
|
logger.step(`Detected type: ${detectedType}`);
|
|
895
896
|
const sections = this.extractSections(text);
|
|
@@ -902,9 +903,13 @@ var ContentAnalyzer = class {
|
|
|
902
903
|
const titles = sections.map((s) => s.header).filter((h) => h.length > 0);
|
|
903
904
|
const starMoments = this.extractStarMoments(text);
|
|
904
905
|
const estimatedSlideCount = Math.max(5, sections.length + 3);
|
|
906
|
+
const whatIsContent = scqa.situation ? [scqa.situation] : [];
|
|
907
|
+
const whatCouldBeContent = scqa.answer ? [scqa.answer] : keyMessages.slice(0, 2);
|
|
905
908
|
return {
|
|
906
909
|
detectedType,
|
|
907
910
|
title,
|
|
911
|
+
subtitle,
|
|
912
|
+
// NEW: Use explicit subtitle from content
|
|
908
913
|
sections,
|
|
909
914
|
keyMessages,
|
|
910
915
|
dataPoints,
|
|
@@ -915,8 +920,10 @@ var ContentAnalyzer = class {
|
|
|
915
920
|
answer: scqa.answer || ""
|
|
916
921
|
},
|
|
917
922
|
sparkline: {
|
|
918
|
-
whatIs:
|
|
919
|
-
|
|
923
|
+
whatIs: whatIsContent,
|
|
924
|
+
// FIX: Use situation, not CTA
|
|
925
|
+
whatCouldBe: whatCouldBeContent,
|
|
926
|
+
// FIX: Use answer/vision, not random messages
|
|
920
927
|
callToAdventure: sparkline.callToAction || ""
|
|
921
928
|
},
|
|
922
929
|
titles,
|
|
@@ -944,18 +951,46 @@ var ContentAnalyzer = class {
|
|
|
944
951
|
return text;
|
|
945
952
|
}
|
|
946
953
|
/**
|
|
947
|
-
* Extract the main title from content
|
|
954
|
+
* Extract the main title AND subtitle from content
|
|
955
|
+
* Subtitle is the line immediately after the H1 title (if not another header)
|
|
948
956
|
*/
|
|
949
|
-
|
|
950
|
-
const
|
|
951
|
-
|
|
952
|
-
|
|
957
|
+
extractTitleAndSubtitle(text) {
|
|
958
|
+
const lines = text.split("\n");
|
|
959
|
+
let title = "Presentation";
|
|
960
|
+
let subtitle = "";
|
|
961
|
+
let foundTitle = false;
|
|
962
|
+
let titleLineIndex = -1;
|
|
963
|
+
for (let i = 0; i < lines.length; i++) {
|
|
964
|
+
const rawLine = lines[i];
|
|
965
|
+
if (!rawLine) continue;
|
|
966
|
+
const line = rawLine.trim();
|
|
967
|
+
const h1Match = line.match(/^#\s+(.+)$/);
|
|
968
|
+
if (h1Match && h1Match[1] && !foundTitle) {
|
|
969
|
+
title = h1Match[1].replace(/\*\*/g, "").trim();
|
|
970
|
+
foundTitle = true;
|
|
971
|
+
titleLineIndex = i;
|
|
972
|
+
continue;
|
|
973
|
+
}
|
|
974
|
+
if (foundTitle && i > titleLineIndex && line.length > 0) {
|
|
975
|
+
if (line.startsWith("#")) break;
|
|
976
|
+
if (line.startsWith("-") || line.startsWith("*") || /^\d+\./.test(line)) break;
|
|
977
|
+
subtitle = line.replace(/\*\*/g, "").trim().slice(0, 100);
|
|
978
|
+
break;
|
|
979
|
+
}
|
|
953
980
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
981
|
+
if (!foundTitle) {
|
|
982
|
+
const firstLine = lines.find((l) => l.trim().length > 0);
|
|
983
|
+
if (firstLine) {
|
|
984
|
+
title = firstLine.replace(/^#+\s*/, "").replace(/\*\*/g, "").trim().slice(0, 80);
|
|
985
|
+
}
|
|
957
986
|
}
|
|
958
|
-
return
|
|
987
|
+
return { title, subtitle };
|
|
988
|
+
}
|
|
989
|
+
/**
|
|
990
|
+
* Extract the main title from content (legacy wrapper)
|
|
991
|
+
*/
|
|
992
|
+
extractTitle(text) {
|
|
993
|
+
return this.extractTitleAndSubtitle(text).title;
|
|
959
994
|
}
|
|
960
995
|
/**
|
|
961
996
|
* Detect presentation type from content signals
|
|
@@ -1578,6 +1613,11 @@ var ContentPatternClassifier = class {
|
|
|
1578
1613
|
}
|
|
1579
1614
|
/**
|
|
1580
1615
|
* Extract timeline/process steps from content
|
|
1616
|
+
* Handles multiple formats:
|
|
1617
|
+
* - "Step 1: Do something" → label: "Step 1", description: "Do something"
|
|
1618
|
+
* - "1. First item" → label: "1", description: "First item"
|
|
1619
|
+
* - "Title - Description text" → label: "Title", description: "Description text"
|
|
1620
|
+
* - "Plain text" → label: "1", description: "Plain text"
|
|
1581
1621
|
*/
|
|
1582
1622
|
extractSteps(section) {
|
|
1583
1623
|
const steps = [];
|
|
@@ -1588,12 +1628,28 @@ var ContentPatternClassifier = class {
|
|
|
1588
1628
|
label: stepMatch[1].trim(),
|
|
1589
1629
|
description: stepMatch[2].trim()
|
|
1590
1630
|
});
|
|
1591
|
-
|
|
1631
|
+
continue;
|
|
1632
|
+
}
|
|
1633
|
+
const dashMatch = bullet.match(/^([^-]+)\s+-\s+(.+)$/);
|
|
1634
|
+
if (dashMatch && dashMatch[1] && dashMatch[2]) {
|
|
1592
1635
|
steps.push({
|
|
1593
|
-
label:
|
|
1594
|
-
description:
|
|
1636
|
+
label: dashMatch[1].trim(),
|
|
1637
|
+
description: dashMatch[2].trim()
|
|
1595
1638
|
});
|
|
1639
|
+
continue;
|
|
1596
1640
|
}
|
|
1641
|
+
const colonMatch = bullet.match(/^([^:]+):\s*(.+)$/);
|
|
1642
|
+
if (colonMatch && colonMatch[1] && colonMatch[2] && colonMatch[1].length < 40) {
|
|
1643
|
+
steps.push({
|
|
1644
|
+
label: colonMatch[1].trim(),
|
|
1645
|
+
description: colonMatch[2].trim()
|
|
1646
|
+
});
|
|
1647
|
+
continue;
|
|
1648
|
+
}
|
|
1649
|
+
steps.push({
|
|
1650
|
+
label: `${steps.length + 1}`,
|
|
1651
|
+
description: bullet
|
|
1652
|
+
});
|
|
1597
1653
|
}
|
|
1598
1654
|
return steps;
|
|
1599
1655
|
}
|
|
@@ -1758,9 +1814,10 @@ var SlideFactory = class {
|
|
|
1758
1814
|
const data = {
|
|
1759
1815
|
title: this.truncateText(analysis.title, this.config.rules.wordsPerSlide.max)
|
|
1760
1816
|
};
|
|
1761
|
-
|
|
1817
|
+
const subtitleSource = analysis.subtitle || analysis.keyMessages[0] || "";
|
|
1818
|
+
if (subtitleSource) {
|
|
1762
1819
|
data.subtitle = this.truncateText(
|
|
1763
|
-
|
|
1820
|
+
subtitleSource,
|
|
1764
1821
|
this.config.defaults.subtitle.maxWords
|
|
1765
1822
|
// FROM KB
|
|
1766
1823
|
);
|
|
@@ -1804,7 +1861,9 @@ var SlideFactory = class {
|
|
|
1804
1861
|
addSCQASlides(slides, analysis) {
|
|
1805
1862
|
const scqa = analysis.scqa;
|
|
1806
1863
|
const titles = this.config.scqaTitles;
|
|
1807
|
-
|
|
1864
|
+
const minBodyLength = 20;
|
|
1865
|
+
const situationBody = scqa?.situation ? this.truncateText(scqa.situation, this.config.rules.wordsPerSlide.max) : "";
|
|
1866
|
+
if (situationBody.length >= minBodyLength && !this.usedContent.has("scqa-situation")) {
|
|
1808
1867
|
this.usedContent.add("scqa-situation");
|
|
1809
1868
|
slides.push({
|
|
1810
1869
|
index: slides.length,
|
|
@@ -1812,12 +1871,13 @@ var SlideFactory = class {
|
|
|
1812
1871
|
data: {
|
|
1813
1872
|
title: titles.situation,
|
|
1814
1873
|
// FROM KB - not hardcoded 'Current Situation'
|
|
1815
|
-
body:
|
|
1874
|
+
body: situationBody
|
|
1816
1875
|
},
|
|
1817
1876
|
classes: ["situation-slide"]
|
|
1818
1877
|
});
|
|
1819
1878
|
}
|
|
1820
|
-
|
|
1879
|
+
const complicationBody = scqa?.complication ? this.truncateText(scqa.complication, this.config.rules.wordsPerSlide.max) : "";
|
|
1880
|
+
if (complicationBody.length >= minBodyLength && !this.usedContent.has("scqa-complication")) {
|
|
1821
1881
|
this.usedContent.add("scqa-complication");
|
|
1822
1882
|
slides.push({
|
|
1823
1883
|
index: slides.length,
|
|
@@ -1825,12 +1885,13 @@ var SlideFactory = class {
|
|
|
1825
1885
|
data: {
|
|
1826
1886
|
title: titles.complication,
|
|
1827
1887
|
// FROM KB - not hardcoded 'The Challenge'
|
|
1828
|
-
body:
|
|
1888
|
+
body: complicationBody
|
|
1829
1889
|
},
|
|
1830
1890
|
classes: ["complication-slide"]
|
|
1831
1891
|
});
|
|
1832
1892
|
}
|
|
1833
|
-
|
|
1893
|
+
const questionBody = scqa?.question ? this.truncateText(scqa.question, this.config.rules.wordsPerSlide.max) : "";
|
|
1894
|
+
if (questionBody.length >= minBodyLength && !this.usedContent.has("scqa-question")) {
|
|
1834
1895
|
this.usedContent.add("scqa-question");
|
|
1835
1896
|
slides.push({
|
|
1836
1897
|
index: slides.length,
|
|
@@ -1838,7 +1899,7 @@ var SlideFactory = class {
|
|
|
1838
1899
|
data: {
|
|
1839
1900
|
title: titles.question,
|
|
1840
1901
|
// FROM KB - not hardcoded 'The Question'
|
|
1841
|
-
body:
|
|
1902
|
+
body: questionBody
|
|
1842
1903
|
},
|
|
1843
1904
|
classes: ["question-slide"]
|
|
1844
1905
|
});
|
|
@@ -1848,7 +1909,8 @@ var SlideFactory = class {
|
|
|
1848
1909
|
const spark = analysis.sparkline;
|
|
1849
1910
|
const titles = this.config.sparklineTitles;
|
|
1850
1911
|
const whatIsFirst = spark?.whatIs?.[0];
|
|
1851
|
-
|
|
1912
|
+
const whatIsBody = whatIsFirst ? this.truncateText(whatIsFirst, this.config.rules.wordsPerSlide.max) : "";
|
|
1913
|
+
if (whatIsBody.length >= 20 && !this.usedContent.has("spark-what-is")) {
|
|
1852
1914
|
this.usedContent.add("spark-what-is");
|
|
1853
1915
|
slides.push({
|
|
1854
1916
|
index: slides.length,
|
|
@@ -1856,13 +1918,14 @@ var SlideFactory = class {
|
|
|
1856
1918
|
data: {
|
|
1857
1919
|
title: titles.whatIs,
|
|
1858
1920
|
// FROM KB - not hardcoded 'Where We Are Today'
|
|
1859
|
-
body:
|
|
1921
|
+
body: whatIsBody
|
|
1860
1922
|
},
|
|
1861
1923
|
classes: ["what-is-slide"]
|
|
1862
1924
|
});
|
|
1863
1925
|
}
|
|
1864
1926
|
const whatCouldBeFirst = spark?.whatCouldBe?.[0];
|
|
1865
|
-
|
|
1927
|
+
const whatCouldBeBody = whatCouldBeFirst ? this.truncateText(whatCouldBeFirst, this.config.rules.wordsPerSlide.max) : "";
|
|
1928
|
+
if (whatCouldBeBody.length >= 20 && !this.usedContent.has("spark-could-be")) {
|
|
1866
1929
|
this.usedContent.add("spark-could-be");
|
|
1867
1930
|
slides.push({
|
|
1868
1931
|
index: slides.length,
|
|
@@ -1870,7 +1933,7 @@ var SlideFactory = class {
|
|
|
1870
1933
|
data: {
|
|
1871
1934
|
title: titles.whatCouldBe,
|
|
1872
1935
|
// FROM KB - not hardcoded 'What Could Be'
|
|
1873
|
-
body:
|
|
1936
|
+
body: whatCouldBeBody
|
|
1874
1937
|
},
|
|
1875
1938
|
classes: ["what-could-be-slide"]
|
|
1876
1939
|
});
|
|
@@ -2079,16 +2142,18 @@ var SlideFactory = class {
|
|
|
2079
2142
|
};
|
|
2080
2143
|
}
|
|
2081
2144
|
createSingleStatementSlide(index, section) {
|
|
2145
|
+
const bodyContent = section.content || section.bullets.join(" ") || "";
|
|
2146
|
+
const truncatedBody = this.truncateText(bodyContent, this.config.rules.wordsPerSlide.max);
|
|
2147
|
+
if (truncatedBody.length < 15 && section.bullets.length > 0) {
|
|
2148
|
+
return this.createBulletSlide(index, section);
|
|
2149
|
+
}
|
|
2082
2150
|
return {
|
|
2083
2151
|
index,
|
|
2084
2152
|
type: "single-statement",
|
|
2085
2153
|
data: {
|
|
2086
2154
|
title: this.createTitle(section.header, section),
|
|
2087
|
-
body:
|
|
2088
|
-
|
|
2089
|
-
this.config.rules.wordsPerSlide.max
|
|
2090
|
-
// FROM KB
|
|
2091
|
-
)
|
|
2155
|
+
body: truncatedBody || section.header
|
|
2156
|
+
// Fallback to header if no body
|
|
2092
2157
|
},
|
|
2093
2158
|
classes: ["single-statement-slide"]
|
|
2094
2159
|
};
|
|
@@ -2462,6 +2527,9 @@ var TemplateEngine = class {
|
|
|
2462
2527
|
this.handlebars.registerHelper("animDelay", function(index, baseMs = 100) {
|
|
2463
2528
|
return `animation-delay: ${index * baseMs}ms`;
|
|
2464
2529
|
});
|
|
2530
|
+
this.handlebars.registerHelper("add", function(a, b) {
|
|
2531
|
+
return a + b;
|
|
2532
|
+
});
|
|
2465
2533
|
this.handlebars.registerHelper("safeHTML", function(text) {
|
|
2466
2534
|
return new Handlebars.SafeString(text);
|
|
2467
2535
|
});
|
|
@@ -2569,7 +2637,12 @@ var TemplateEngine = class {
|
|
|
2569
2637
|
this.templates.set("single-statement", this.handlebars.compile(`
|
|
2570
2638
|
<section class="{{classes}}" data-slide-index="{{slideIndex}}" style="{{styles}}">
|
|
2571
2639
|
<div class="slide-content statement-content">
|
|
2640
|
+
{{#if body}}
|
|
2641
|
+
<h2 class="title animate-fadeIn">{{title}}</h2>
|
|
2642
|
+
<p class="statement animate-fadeIn delay-200">{{markdown body}}</p>
|
|
2643
|
+
{{else}}
|
|
2572
2644
|
<p class="statement animate-fadeIn">{{title}}</p>
|
|
2645
|
+
{{/if}}
|
|
2573
2646
|
</div>
|
|
2574
2647
|
{{> speakerNotes}}
|
|
2575
2648
|
</section>
|
|
@@ -2635,14 +2708,30 @@ var TemplateEngine = class {
|
|
|
2635
2708
|
<h2 class="title animate-fadeIn">{{title}}</h2>
|
|
2636
2709
|
<div class="columns two-columns">
|
|
2637
2710
|
<div class="column column-left animate-slideRight">
|
|
2638
|
-
{{#if
|
|
2639
|
-
|
|
2711
|
+
{{#if leftColumn.title}}<h3>{{leftColumn.title}}</h3>{{/if}}
|
|
2712
|
+
{{#if leftColumn.body}}
|
|
2713
|
+
<p class="body">{{markdown leftColumn.body}}</p>
|
|
2640
2714
|
{{/if}}
|
|
2641
|
-
{{#if
|
|
2642
|
-
|
|
2715
|
+
{{#if leftColumn.bullets}}
|
|
2716
|
+
<ul class="bullets stagger-children">
|
|
2717
|
+
{{#each leftColumn.bullets}}
|
|
2718
|
+
<li class="bullet animate-fadeIn" style="{{animDelay @index 150}}">{{markdown this}}</li>
|
|
2719
|
+
{{/each}}
|
|
2720
|
+
</ul>
|
|
2643
2721
|
{{/if}}
|
|
2644
2722
|
</div>
|
|
2645
2723
|
<div class="column column-right animate-slideLeft delay-200">
|
|
2724
|
+
{{#if rightColumn.title}}<h3>{{rightColumn.title}}</h3>{{/if}}
|
|
2725
|
+
{{#if rightColumn.body}}
|
|
2726
|
+
<p class="body">{{markdown rightColumn.body}}</p>
|
|
2727
|
+
{{/if}}
|
|
2728
|
+
{{#if rightColumn.bullets}}
|
|
2729
|
+
<ul class="bullets stagger-children">
|
|
2730
|
+
{{#each rightColumn.bullets}}
|
|
2731
|
+
<li class="bullet animate-fadeIn" style="{{animDelay @index 150}}">{{markdown this}}</li>
|
|
2732
|
+
{{/each}}
|
|
2733
|
+
</ul>
|
|
2734
|
+
{{/if}}
|
|
2646
2735
|
{{#if hasImage}}
|
|
2647
2736
|
{{> imageWithCaption images.[0]}}
|
|
2648
2737
|
{{else if metrics}}
|
|
@@ -2663,11 +2752,13 @@ var TemplateEngine = class {
|
|
|
2663
2752
|
{{#each columns}}
|
|
2664
2753
|
<div class="column animate-fadeIn" style="{{animDelay @index 200}}">
|
|
2665
2754
|
{{#if title}}<h3 class="column-title">{{title}}</h3>{{/if}}
|
|
2755
|
+
{{#if content}}<p class="column-body">{{markdown content}}</p>{{/if}}
|
|
2666
2756
|
{{#if body}}<p class="column-body">{{markdown body}}</p>{{/if}}
|
|
2667
2757
|
{{#if icon}}<div class="column-icon">{{icon}}</div>{{/if}}
|
|
2668
2758
|
</div>
|
|
2669
2759
|
{{/each}}
|
|
2670
2760
|
</div>
|
|
2761
|
+
{{> source}}
|
|
2671
2762
|
</div>
|
|
2672
2763
|
{{> speakerNotes}}
|
|
2673
2764
|
</section>
|
|
@@ -2676,25 +2767,24 @@ var TemplateEngine = class {
|
|
|
2676
2767
|
<section class="{{classes}}" data-slide-index="{{slideIndex}}" style="{{styles}}">
|
|
2677
2768
|
<div class="slide-content">
|
|
2678
2769
|
<h2 class="title animate-fadeIn">{{title}}</h2>
|
|
2679
|
-
<div class="comparison-container">
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
<
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
</div>
|
|
2688
|
-
<div class="comparison-divider"></div>
|
|
2689
|
-
<div class="comparison-right animate-slideLeft delay-200">
|
|
2690
|
-
<h3>{{rightTitle}}</h3>
|
|
2770
|
+
<div class="comparison-container columns two-columns">
|
|
2771
|
+
{{#each columns}}
|
|
2772
|
+
<div class="column comparison-{{#if @first}}left animate-slideRight{{else}}right animate-slideLeft delay-200{{/if}}">
|
|
2773
|
+
<h3 class="column-title">{{title}}</h3>
|
|
2774
|
+
{{#if content}}
|
|
2775
|
+
<p class="column-content">{{markdown content}}</p>
|
|
2776
|
+
{{/if}}
|
|
2777
|
+
{{#if bullets}}
|
|
2691
2778
|
<ul>
|
|
2692
|
-
{{#each
|
|
2779
|
+
{{#each bullets}}
|
|
2693
2780
|
<li>{{this}}</li>
|
|
2694
2781
|
{{/each}}
|
|
2695
2782
|
</ul>
|
|
2783
|
+
{{/if}}
|
|
2696
2784
|
</div>
|
|
2785
|
+
{{/each}}
|
|
2697
2786
|
</div>
|
|
2787
|
+
{{> source}}
|
|
2698
2788
|
</div>
|
|
2699
2789
|
{{> speakerNotes}}
|
|
2700
2790
|
</section>
|
|
@@ -2758,18 +2848,18 @@ var TemplateEngine = class {
|
|
|
2758
2848
|
<section class="{{classes}}" data-slide-index="{{slideIndex}}" style="{{styles}}">
|
|
2759
2849
|
<div class="slide-content">
|
|
2760
2850
|
<h2 class="title animate-fadeIn">{{title}}</h2>
|
|
2761
|
-
<div class="timeline stagger-children">
|
|
2762
|
-
{{#each
|
|
2763
|
-
<div class="timeline-item animate-fadeIn" style="{{animDelay @index 200}}">
|
|
2764
|
-
<div class="
|
|
2851
|
+
<div class="timeline steps stagger-children">
|
|
2852
|
+
{{#each steps}}
|
|
2853
|
+
<div class="step timeline-item animate-fadeIn" style="{{animDelay @index 200}}">
|
|
2854
|
+
<div class="step-number">{{add @index 1}}</div>
|
|
2765
2855
|
<div class="timeline-content">
|
|
2766
|
-
<div class="
|
|
2767
|
-
<div class="
|
|
2768
|
-
{{#if description}}<div class="timeline-desc">{{description}}</div>{{/if}}
|
|
2856
|
+
<div class="step-title">{{label}}</div>
|
|
2857
|
+
{{#if description}}<div class="step-desc">{{description}}</div>{{/if}}
|
|
2769
2858
|
</div>
|
|
2770
2859
|
</div>
|
|
2771
2860
|
{{/each}}
|
|
2772
2861
|
</div>
|
|
2862
|
+
{{> source}}
|
|
2773
2863
|
</div>
|
|
2774
2864
|
{{> speakerNotes}}
|
|
2775
2865
|
</section>
|
|
@@ -5307,29 +5397,70 @@ ${slides}
|
|
|
5307
5397
|
}
|
|
5308
5398
|
|
|
5309
5399
|
/* Comparison slides: Split visual */
|
|
5310
|
-
.reveal .slide-comparison .columns
|
|
5400
|
+
.reveal .slide-comparison .columns,
|
|
5401
|
+
.reveal .slide-comparison .comparison-container {
|
|
5311
5402
|
gap: 60px;
|
|
5312
5403
|
}
|
|
5313
|
-
.reveal .slide-comparison .column:first-child
|
|
5404
|
+
.reveal .slide-comparison .column:first-child,
|
|
5405
|
+
.reveal .slide-comparison .comparison-left {
|
|
5314
5406
|
border-right: 2px solid ${this.lightenColor(secondary, 70)};
|
|
5315
5407
|
padding-right: 30px;
|
|
5316
5408
|
}
|
|
5409
|
+
.reveal .column-title {
|
|
5410
|
+
font-size: 1.2em;
|
|
5411
|
+
font-weight: 600;
|
|
5412
|
+
margin-bottom: 0.5em;
|
|
5413
|
+
color: var(--color-accent);
|
|
5414
|
+
}
|
|
5415
|
+
.reveal .column-content,
|
|
5416
|
+
.reveal .column-body {
|
|
5417
|
+
line-height: 1.6;
|
|
5418
|
+
}
|
|
5317
5419
|
|
|
5318
5420
|
/* Timeline/Process: Visual flow */
|
|
5319
5421
|
.reveal .slide-timeline .steps,
|
|
5320
|
-
.reveal .slide-
|
|
5422
|
+
.reveal .slide-timeline .timeline,
|
|
5423
|
+
.reveal .slide-process .steps,
|
|
5424
|
+
.reveal .slide-process .process-steps {
|
|
5321
5425
|
display: flex;
|
|
5322
5426
|
gap: 20px;
|
|
5427
|
+
flex-wrap: wrap;
|
|
5428
|
+
justify-content: center;
|
|
5323
5429
|
}
|
|
5324
5430
|
.reveal .slide-timeline .step,
|
|
5325
|
-
.reveal .slide-
|
|
5431
|
+
.reveal .slide-timeline .timeline-item,
|
|
5432
|
+
.reveal .slide-process .step,
|
|
5433
|
+
.reveal .slide-process .process-step {
|
|
5326
5434
|
flex: 1;
|
|
5435
|
+
min-width: 150px;
|
|
5436
|
+
max-width: 250px;
|
|
5327
5437
|
padding: 20px;
|
|
5328
5438
|
background: ${isDark ? this.lightenColor(background, 10) : this.lightenColor(secondary, 92)};
|
|
5329
5439
|
border-radius: 8px;
|
|
5330
5440
|
border-top: 4px solid var(--color-accent);
|
|
5331
5441
|
${isDark ? `color: ${text};` : ""}
|
|
5332
5442
|
}
|
|
5443
|
+
.reveal .step-number {
|
|
5444
|
+
font-size: 1.5em;
|
|
5445
|
+
font-weight: 700;
|
|
5446
|
+
color: var(--color-accent);
|
|
5447
|
+
margin-bottom: 0.5em;
|
|
5448
|
+
}
|
|
5449
|
+
.reveal .step-title {
|
|
5450
|
+
font-size: 1.1em;
|
|
5451
|
+
font-weight: 600;
|
|
5452
|
+
margin-bottom: 0.5em;
|
|
5453
|
+
}
|
|
5454
|
+
.reveal .step-desc {
|
|
5455
|
+
font-size: 0.9em;
|
|
5456
|
+
color: var(--color-text-light);
|
|
5457
|
+
}
|
|
5458
|
+
.reveal .step-arrow {
|
|
5459
|
+
display: flex;
|
|
5460
|
+
align-items: center;
|
|
5461
|
+
font-size: 1.5em;
|
|
5462
|
+
color: var(--color-accent);
|
|
5463
|
+
}
|
|
5333
5464
|
|
|
5334
5465
|
/* Progress bar enhancement */
|
|
5335
5466
|
.reveal .progress {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-presentation-master",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.4.0",
|
|
4
4
|
"description": "Generate world-class presentations using expert methodologies from Duarte, Reynolds, Gallo, and Anderson. Enforces rigorous quality standards through real visual validation.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|