@topmindspace/tms-skills 0.1.17 → 0.1.19
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/CHANGELOG.md +84 -0
- package/README.en.md +3 -3
- package/README.md +3 -3
- package/package.json +1 -1
- package/top-ppt-html/README.en.md +2 -2
- package/top-ppt-html/README.md +1 -1
- package/top-ppt-html/SKILL.md +4 -4
- package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.html +144 -58
- package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.html +144 -58
- package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.html +144 -58
- package/top-ppt-html/assets/examples/2026-09-26-topmind-tms-skills-showcase.html +214 -211
- package/top-ppt-html/assets/examples/2026-09-26-topmind-tms-skills-showcase.model.json +33 -39
- package/top-ppt-html/assets/pptx-export.js +120 -46
- package/top-ppt-html/assets/style-gallery.html +21 -4
- package/top-ppt-html/assets/templates/architecture.html +158 -61
- package/top-ppt-html/assets/templates/engine.css +23 -11
- package/top-ppt-html/assets/templates/presentation.html +158 -63
- package/top-ppt-html/assets/templates/research.html +164 -69
- package/top-ppt-html/package-lock.json +2 -2
- package/top-ppt-html/package.json +1 -1
- package/top-ppt-html/references/chart-decision-tree.md +26 -25
- package/top-ppt-html/references/components-atoms.md +5 -4
- package/top-ppt-html/references/content-rules.md +17 -9
- package/top-ppt-html/references/failure-modes.md +31 -3
- package/top-ppt-html/references/high-fidelity.md +14 -1
- package/top-ppt-html/references/icons.md +2 -2
- package/top-ppt-html/references/layout-grammar.md +3 -1
- package/top-ppt-html/references/layouts-combo.md +1 -1
- package/top-ppt-html/references/layouts-research.md +1 -1
- package/top-ppt-html/references/modes.md +1 -1
- package/top-ppt-html/references/page-type-matrix.md +10 -6
- package/top-ppt-html/references/pptx-export.md +5 -5
- package/top-ppt-html/references/tech-design.md +2 -0
- package/top-ppt-html/scripts/build_icon_assets.js +92 -0
- package/top-ppt-html/scripts/build_pptx.js +226 -71
- package/top-ppt-html/scripts/cross_verify.py +84 -1
- package/top-ppt-html/scripts/extract_model.py +26 -1
- package/top-ppt-html/scripts/icon_lib.js +53 -0
- package/top-ppt-html/scripts/icon_raster.js +86 -0
- package/top-ppt-html/scripts/layout-constants.json +45 -2
- package/top-ppt-html/scripts/lib_layout_regions.js +9 -4
- package/top-ppt-html/scripts/model-schema.json +8 -3
- package/top-ppt-html/scripts/package_skill.py +1 -0
- package/top-ppt-html/scripts/render_from_model.py +254 -37
- package/top-ppt-html/scripts/scaffold_report.py +47 -24
- package/top-ppt-html/scripts/sync_runtime.py +21 -4
- package/top-ppt-html/scripts/test_feedback_gates.py +73 -0
- package/top-ppt-html/scripts/validate_pptx.py +162 -3
- package/top-ppt-html/scripts/validate_report.py +24 -0
|
@@ -332,7 +332,13 @@ border-color:color-mix(in srgb,var(--accent-on) 20%,transparent);color:var(--acc
|
|
|
332
332
|
rows-2 / rows-3:等高行分区(纵向节奏,替代等高卡片堆叠) */
|
|
333
333
|
.g-211{grid-template-columns:minmax(0,2fr) minmax(0,1fr) minmax(0,1fr)}
|
|
334
334
|
.g-121{grid-template-columns:minmax(0,1fr) minmax(0,2fr) minmax(0,1fr)}
|
|
335
|
-
.g-quad{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:minmax(
|
|
335
|
+
.g-quad{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:minmax(min-content,1fr);align-items:stretch}
|
|
336
|
+
.g-half{grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);align-items:stretch}
|
|
337
|
+
@media (max-width:1180px){.g-half{grid-template-columns:1fr}}
|
|
338
|
+
.g-2--equal,.g-3--equal,.g-4--equal{grid-auto-rows:minmax(min-content,1fr);align-items:stretch}
|
|
339
|
+
.grid.g-2>.card,.grid.g-3>.card,.grid.g-4>.card,
|
|
340
|
+
.grid.g-quad>.card,.grid.g-half>.card,.grid.g-2--equal>.card,
|
|
341
|
+
.grid.g-3--equal>.card,.grid.g-4--equal>.card{align-self:stretch}
|
|
336
342
|
.g-aside{grid-template-columns:minmax(0,1fr) minmax(200px,.36fr);align-items:start}
|
|
337
343
|
.g-aside__side{position:sticky;top:calc(var(--bar-h) + 16px)}
|
|
338
344
|
.g-mosaic{grid-template-columns:repeat(3,minmax(0,1fr));
|
|
@@ -348,7 +354,7 @@ grid-template-areas:"main main main" "s1 s2 s3"}
|
|
|
348
354
|
.kv--2col{grid-template-columns:auto minmax(0,1fr) auto minmax(0,1fr)}
|
|
349
355
|
/* ── 拼贴栅格 g-bento(Bento / 马赛克):4 列基准 + 跨列/跨行工具类 ──
|
|
350
356
|
.sp-2/.sp-3/.sp-4 跨列(span),.rw-2 跨行;窄屏自动降列并收敛 span。 */
|
|
351
|
-
.g-bento{grid-template-columns:repeat(4,minmax(0,1fr));grid-auto-rows:minmax(
|
|
357
|
+
.g-bento{grid-template-columns:repeat(4,minmax(0,1fr));grid-auto-rows:minmax(min-content,1fr)}
|
|
352
358
|
.sp-2{grid-column:span 2}.sp-3{grid-column:span 3}.sp-4{grid-column:span 4}
|
|
353
359
|
.rw-2{grid-row:span 2}
|
|
354
360
|
@media (max-width:1180px){.g-bento{grid-template-columns:repeat(2,minmax(0,1fr))}
|
|
@@ -383,19 +389,21 @@ background:color-mix(in srgb,var(--bg) 86%,transparent);
|
|
|
383
389
|
backdrop-filter:saturate(160%) blur(14px);-webkit-backdrop-filter:saturate(160%) blur(14px);
|
|
384
390
|
border-bottom:1px solid var(--border-soft);
|
|
385
391
|
transition:height var(--dur-medium) var(--ease-standard)}
|
|
386
|
-
.bar__in{height:100%;display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4)}
|
|
387
|
-
.brand{display:flex;align-items:center;gap:var(--sp-3);min-width:0}
|
|
392
|
+
.bar__in{height:100%;display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);overflow:hidden}
|
|
393
|
+
.brand{display:flex;align-items:center;gap:var(--sp-3);min-width:0;flex:1 1 auto;overflow:hidden}
|
|
388
394
|
.brand__mark{width:34px;height:34px;flex:none;border-radius:10px;background:var(--accent);
|
|
389
395
|
color:var(--accent-on);display:grid;place-items:center;font-size:13px;font-weight:700}
|
|
396
|
+
.brand__txt{min-width:0;overflow:hidden;flex:1 1 auto}
|
|
390
397
|
.brand__title{font-size:var(--fs-sm);font-weight:600;color:var(--text);white-space:nowrap;
|
|
391
|
-
overflow:hidden;text-overflow:ellipsis}
|
|
398
|
+
overflow:hidden;text-overflow:ellipsis;max-width:100%}
|
|
392
399
|
.brand__sub{font-size:var(--fs-xs);color:var(--text-3);white-space:nowrap;overflow:hidden;
|
|
393
|
-
text-overflow:ellipsis}
|
|
394
|
-
.nav{display:flex;align-items:center;gap:var(--sp-1)}
|
|
400
|
+
text-overflow:ellipsis;max-width:100%}
|
|
401
|
+
.nav{display:flex;align-items:center;gap:var(--sp-1);flex:0 1 auto;min-width:0;overflow:hidden}
|
|
395
402
|
.nav a{padding:8px 14px;border-radius:var(--r-full);color:var(--text-2);text-decoration:none;
|
|
396
403
|
font-size:var(--fs-sm);font-weight:500;white-space:nowrap;transition:background-color var(--dur-short),color var(--dur-short)}
|
|
397
404
|
.nav a:hover{background:var(--surface-2);color:var(--text)}
|
|
398
405
|
@media (max-width:1180px){.nav{display:none}}
|
|
406
|
+
@media (max-width:1360px){.brand__sub{display:none}}
|
|
399
407
|
.iconbtn{width:40px;height:40px;flex:none;display:grid;place-items:center;
|
|
400
408
|
border:1px solid var(--border);border-radius:var(--r-full);background:transparent;
|
|
401
409
|
color:var(--text-2);cursor:pointer;transition:background-color var(--dur-short),color var(--dur-short)}
|
|
@@ -450,12 +458,15 @@ transition:background-color var(--dur-short),box-shadow var(--dur-short),transfo
|
|
|
450
458
|
.btn--ghost{background:transparent;color:var(--text);border-color:var(--border)}
|
|
451
459
|
.btn--onDark{background:var(--surface);color:var(--text)}
|
|
452
460
|
.card{background:var(--surface);border:1px solid var(--border-soft);border-radius:var(--r-lg);
|
|
453
|
-
padding:clamp(20px,2vw,30px);transition:border-color var(--dur-short),box-shadow var(--dur-short),background-color var(--dur-medium)
|
|
461
|
+
padding:clamp(20px,2vw,30px);transition:border-color var(--dur-short),box-shadow var(--dur-short),background-color var(--dur-medium);
|
|
462
|
+
display:flex;flex-direction:column;min-width:0}
|
|
454
463
|
.card:hover{border-color:var(--border);box-shadow:var(--shadow-1)}
|
|
455
464
|
.card--flat{background:var(--surface-1);border-color:transparent}
|
|
456
465
|
.card--flat:hover{background:var(--surface-2)}
|
|
457
466
|
.card--accent{background:var(--accent-soft);border-color:transparent}
|
|
458
|
-
.card__hd{display:flex;align-items:center;gap:var(--sp-3);margin-bottom:var(--sp-3)}
|
|
467
|
+
.card__hd{display:flex;align-items:center;gap:var(--sp-3);margin-bottom:var(--sp-3);flex:none}
|
|
468
|
+
.card>.ul,.card>.t-body,.card>.t-sm{flex:1 1 auto}
|
|
469
|
+
.card>.so-what,.card>.tbd-legend,.card>.flagbar{flex:none;margin-top:auto}
|
|
459
470
|
.card__ico{width:34px;height:34px;flex:none;border-radius:10px;background:var(--accent-soft);
|
|
460
471
|
color:var(--accent-text);display:grid;place-items:center;font-size:15px;font-weight:600}
|
|
461
472
|
.card__ico svg{width:18px;height:18px}
|
|
@@ -817,8 +828,9 @@ color:var(--accent);font-variant-numeric:tabular-nums;line-height:1;min-width:2.
|
|
|
817
828
|
.agenda__a:hover .agenda__go{color:var(--accent);transform:translateX(4px)}
|
|
818
829
|
.agenda__go svg{width:20px;height:20px;display:block}
|
|
819
830
|
@media (min-width:900px){
|
|
820
|
-
|
|
821
|
-
.agenda--2col
|
|
831
|
+
/* R4:列优先(先左列后右列),与 PPTX Agenda 列填充一致——grid 行优先会打乱阅读顺序 */
|
|
832
|
+
.agenda--2col{display:block;column-count:2;column-gap:clamp(20px,3vw,48px)}
|
|
833
|
+
.agenda--2col .agenda__i{break-inside:avoid;border-top:1px solid var(--border-soft)}}
|
|
822
834
|
/* ── 页码指示(翻页导航) ── */
|
|
823
835
|
.pager{position:fixed;right:clamp(10px,1.6vw,26px);top:50%;transform:translateY(-50%);
|
|
824
836
|
z-index:60;display:flex;flex-direction:column;align-items:center;gap:10px}
|
|
@@ -1993,7 +2005,7 @@ window.REPORT_MODEL = {
|
|
|
1993
2005
|
|
|
1994
2006
|
/* __TOPPPT_RUNTIME_START__ */
|
|
1995
2007
|
/* ══ PPTX 导出运行时(assets/pptx-export.js 的内联副本 · 由 scripts/sync_runtime.py 注入,禁止手改) ══ */
|
|
1996
|
-
/* __TOPPPT_RUNTIME_SHA__:
|
|
2008
|
+
/* __TOPPPT_RUNTIME_SHA__:af6e25f25fd2e116 */
|
|
1997
2009
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
1998
2010
|
* TopPPT HTML· 浏览器端 PPTX 预览运行时
|
|
1999
2011
|
* 零依赖、随报告单文件分发;OOXML 序列化器(仅供预览,页面不导出文件)。
|
|
@@ -2117,7 +2129,8 @@ function regionOf(pageType, slotId, opts) {
|
|
|
2117
2129
|
if (type === 'bar' && slot === 'primary') {
|
|
2118
2130
|
var by = P.chartY || 2.95;
|
|
2119
2131
|
var bb = opts.bottom != null ? opts.bottom : bottomDefault;
|
|
2120
|
-
|
|
2132
|
+
/* chartX/chartW 历史误用已纠正:与 donut/table/hbar/exhibit 同口径,图表盒对齐版心 (MX, CW) */
|
|
2133
|
+
return { x: MX, y: by, w: CW, h: Math.max(1.2, bb - by) };
|
|
2121
2134
|
}
|
|
2122
2135
|
if (type === 'bar' && slot === 'hbar') {
|
|
2123
2136
|
var y0 = P.hbarY0 || 2.6;
|
|
@@ -2152,6 +2165,15 @@ function regionOf(pageType, slotId, opts) {
|
|
|
2152
2165
|
return { x: MX, y: P.heroY || 2.9, w: CW * (P.heroW || 0.52), h: P.heroH || 1.6,
|
|
2153
2166
|
dividerX: P.dividerX, metricY0: P.metricY0, metricRowH: P.metricRowH };
|
|
2154
2167
|
}
|
|
2168
|
+
/* R3:kpi 支撑指标列——落在 dividerX 右侧(默认全宽返回会压住 hero) */
|
|
2169
|
+
if (type === 'kpi' && slot === 'metrics') {
|
|
2170
|
+
var dxK = P.dividerX != null ? P.dividerX : 0.56;
|
|
2171
|
+
return {
|
|
2172
|
+
x: MX + CW * dxK + 0.35, y: P.metricY0 || 2.95,
|
|
2173
|
+
w: CW * (1 - dxK) - 0.5,
|
|
2174
|
+
h: Math.max(0.6, bottomDefault - (P.metricY0 || 2.95)),
|
|
2175
|
+
};
|
|
2176
|
+
}
|
|
2155
2177
|
if (type === 'comparison' && (slot === 'left' || slot === 'primary' || slot === 'right')) {
|
|
2156
2178
|
var cg = P.panelGap || 0.4, pw = (CW - cg) / 2;
|
|
2157
2179
|
if (slot === 'right') return { x: MX + pw + cg, y: P.panelY || 2.55, w: pw, h: P.panelH || 3.4 };
|
|
@@ -2184,15 +2206,22 @@ function regionOf(pageType, slotId, opts) {
|
|
|
2184
2206
|
}
|
|
2185
2207
|
if (type === 'image' && slot === 'primary') {
|
|
2186
2208
|
var iy2 = Math.max(P.y || 2.3, opts.top || 0);
|
|
2187
|
-
|
|
2209
|
+
/* R2:有图注时图片不得越过 contentBottomWithNote(图注落注释带,属 annotation self) */
|
|
2210
|
+
var iBottom = (opts.bottom != null) ? opts.bottom
|
|
2211
|
+
: (opts.caption ? (L.contentBottomWithNote || 6.4) : bottomDefault);
|
|
2212
|
+
return { x: MX, y: iy2, w: CW, h: Math.max(1.2, Math.min(P.h || 4.2, iBottom - iy2)) };
|
|
2188
2213
|
}
|
|
2189
2214
|
if ((type === 'halftable') && (slot === 'left' || slot === 'primary')) {
|
|
2190
2215
|
var rs = PT.research || {};
|
|
2191
|
-
|
|
2216
|
+
var ht = opts.top != null ? opts.top : topDefault;
|
|
2217
|
+
var hb = opts.bottom != null ? opts.bottom : bottomDefault;
|
|
2218
|
+
return { x: MX, y: ht, w: CW * (rs.halfTableW || 0.52), h: Math.max(1, hb - ht) };
|
|
2192
2219
|
}
|
|
2193
2220
|
if ((type === 'halftable') && (slot === 'right' || slot === 'secondary')) {
|
|
2194
2221
|
var rs2 = PT.research || {};
|
|
2195
|
-
|
|
2222
|
+
var ht2 = opts.top != null ? opts.top : topDefault;
|
|
2223
|
+
var hb2 = opts.bottom != null ? opts.bottom : bottomDefault;
|
|
2224
|
+
return { x: MX + CW * (rs2.halfChartX || 0.57), y: ht2, w: CW * (rs2.halfChartW || 0.43), h: Math.max(1, hb2 - ht2) };
|
|
2196
2225
|
}
|
|
2197
2226
|
if (type === 'matrix' && slot === 'primary') {
|
|
2198
2227
|
var rm = PT.research || {};
|
|
@@ -2213,7 +2242,7 @@ function regionOf(pageType, slotId, opts) {
|
|
|
2213
2242
|
/* __TOPPPT_SCHEMA_START__ */
|
|
2214
2243
|
/* ── 由 scripts/sync_runtime.py 从 scripts/model-schema.json 注入 · 禁止手改 ── */
|
|
2215
2244
|
/* DSL schema 单源:浏览器端 validateModel 与 scripts/extract_model.py 消费同一份定义 */
|
|
2216
|
-
var MODEL_SCHEMA = {"version":"0.1","modes":["presentation","research","architecture"],"model":{"required":["title","sections:array","closing.title","closing.points:array"],"optional":["mode","style","theme","subtitle","meta","agenda:array"],"agendaMin":{"presentation":3,"research":3,"architecture":0},"sectionsMin":1,"sectionsRecommended":3,"agendaComfortMax":
|
|
2245
|
+
var MODEL_SCHEMA = {"version":"0.1","modes":["presentation","research","architecture"],"model":{"required":["title","sections:array","closing.title","closing.points:array"],"optional":["mode","style","theme","subtitle","meta","agenda:array"],"agendaMin":{"presentation":3,"research":3,"architecture":0},"agendaMax":7,"agendaMaxWithRefs":8,"agendaHint":"agenda 条目 = 章(篇/section),3–7 条;每章可含多页(sections[] 按页建模)。禁止把逐页标题当大纲。sections[].eyebrow 的 `NN ·` 前缀 = 章键,须与某条 agenda 对应;跳转锚点 = 该章第一页。含「参考资料」条目时 +1 仍 ≤8。","sectionsMin":1,"sectionsRecommended":3,"agendaComfortMax":8},"commonSectionFields":["eyebrow","title","lead","soWhat","footnote","flags","image","exhibitNo","layoutPreset"],"mutualExclusionHint":"verdict 与 soWhat 互斥:二者共用 annotation 结论条槽位,同页双填必叠印。comparison 页填 verdict 时不要再填 soWhat(渲染器已自动二选一,但模型侧应只给一个)。","flagsHint":"flags = 待核实/待二次修改条目字符串数组(如 '2027 增速 xx%(口径未定)');渲染为 accent 强调色标注行,提示用户核对。","imageHint":"image = 素材图片/配图占位对象。三选一必填:src(用户图,data: 内联或相对路径,零外链铁律禁 http(s))|items(多图版式:grid/compare/wall,元素 {src?, alt?, caption?, placeholder?})|placeholder:true(无图时出配图占位,原生形状渲染、pictures 不增)。其余可选:layout(full/half/bleed/grid/compare/wall,见 layout-constants.json imageSpec.layouts)、fit(cover 默认 / contain)、caption、alt、hint、ratio。","imageLayoutHint":"layout 与 HTML 版式对应:full=版心全宽图|half=左图右注(points 为右栏注解)|bleed=通栏出血|grid=多图网格(items 2/3/4/6 张)|compare=双图 A/B 对比(items 2 张)|wall=Logo 墙(items 3–12 张小图)。占位符标签文本由双引擎按 imageSpec 拼同一串,保证 A/B 通道逐页文本一致。","chartTypes":["bar","hbar","stack","stackline","line","dualline","area","donut","multidonut","pie","radar","scatter","bubble","waterfall","gauge","pareto","funnel","gantt","vsbar","progress","sparkline","slope","dumbbell","lollipop","dotplot","bulletchart","waffle","radialbar","rose","candlestick"],"chartTypesHint":"chart.type 可取值 = 本表(30 类:16 原生 + 14 形状还原)。其余 6 类复杂信息图(sankey/treemap/boxplot/network/marimekko/streamgraph)是**专属页型**而非 chart.type——它们要按列/段/节点等结构化载荷表达,故走 sections[].type。不变量:charts.registry.types == chartTypes ∪ 上述 6 类页型(sync_runtime.py 校验)。","chartDataTable":{"enum":["notes","inline","appendix","off"],"default":"notes","rule":"非原生图表(registry.pptx=shape)的 dataTable 不得为 off;缺失时按 registry 默认值补齐。"},"pageTypes":{"points":{"label":"要点列表页","modes":["presentation","research","architecture"],"required":["points:array"],"optional":["metrics:array"]},"metrics":{"label":"指标带页(4–6 个核心数字)","modes":["presentation","research"],"required":["metrics:array"]},"kpi":{"label":"大数指标页(hero 大数字 + 支撑指标行)","modes":["presentation","research"],"required":["hero:array"],"optional":["metrics:array"]},"table":{"label":"对比表页","modes":["presentation","research","architecture"],"required":["table.head:array","table.rows:array"],"optional":["table.colW:array"]},"timeline":{"label":"时间线 / 路线页","modes":["presentation","research"],"required":["phases:array"]},"steps":{"label":"步骤条页(N 步横排 + 箭头,可分组)","modes":["presentation","research","architecture"],"required":["steps:array"],"optional":["groups:array","note"]},"bar":{"label":"图表页(chart.type 见 chartTypes;native 通道走原生数据图表,shape 通道走高保真形状还原 + 数据表)","modes":["presentation","research"],"required":["chart.labels:array","chart.values:array"],"optional":["chart.type","chart.series:array","chart.points:array","chart.max","chart.unit","chart.colors:array","chart.start:array","chart.target:array","chart.dataTable","note"]},"donut":{"label":"环形图页(原生 pie 楔形 + 图例)","modes":["presentation","research"],"required":["chart.labels:array","chart.values:array"],"optional":["chart.unit","chart.centerLabel","chart.colors:array","chart.dataTable","note"]},"heatmap":{"label":"热力矩阵页(行 × 列 + 强度色阶)","modes":["presentation","research"],"required":["rowHeads:array","colHeads:array","cells:array"],"optional":["unit","scaleLabel:array","note"]},"bullet":{"label":"达成对比页(实际 vs 目标条)","modes":["presentation","research"],"required":["items:array"],"optional":["unit","max","note"]},"pyramid":{"label":"金字塔页(层级递进,顶层最窄)","modes":["presentation","research","architecture"],"required":["levels:array"],"optional":["note"]},"image":{"label":"素材图片页(full/half/bleed/grid/compare/wall,效果与位置锁定;支持配图占位)","modes":["presentation","research","architecture"],"required":["anyof:image.src:str|image.items:array|image.placeholder"],"optional":["image.caption","image.alt","image.layout","image.fit","image.ratio","image.hint","points:array","note"]},"cards":{"label":"卡片网格页(cards 元素须为 {title, points:[[k,v]…], icon?},不接受元组)","modes":["presentation","research"],"required":["cards:array"],"optional":["columns"],"cardItemHint":"cards[] 元素:{title:str, points:[[k,v]…]|[{t,d}…]|[str…], icon?:str}。icon = 语义图标名(icon_lib.js 键:增长/下降/数据/图表/趋势/占比/表格/效率/成果/安全/权限/检查/风险/团队/流程/计划/智能/洞察/工具/清单),HTML 与 PPTX 同名真导出;缺省按标题语义自动挑选。"},"split":{"label":"双区组合页(left / right 各可为 要点|图表|表格|图片:type = points(默认)| table | image | 图表类型名;图表/表格字段直接挂在对应侧)","modes":["presentation","research"],"required":["anyof:left.points:array|left.type:str"],"optional":["left.cap","left.image","left.labels:array","left.values:array","left.series:array","left.points:array","left.max","left.unit","left.colors:array","left.dataTable","left.head:array","left.rows:array","left.colW:array","right.type","right.cap","right.image","right.labels:array","right.values:array","right.series:array","right.points:array","right.max","right.unit","right.colors:array","right.dataTable","right.head:array","right.rows:array","right.colW:array"]},"comparison":{"label":"对比页(左右双栏 + 可选结论条)","modes":["presentation","research"],"required":["left.title","left.points:array","right.title","right.points:array"],"optional":["verdict"]},"quote":{"label":"引用 / 金句页(深色全幅)","modes":["presentation","research"],"required":["quote","author"],"optional":["context"]},"diagram":{"label":"分层架构页(architecture 模式走全幅几何)","modes":["presentation","research","architecture"],"required":["layers:array"],"optional":["legend:array"]},"exhibit":{"label":"Exhibit 编号图表页(research R2)","modes":["research"],"required":["chart.labels:array","chart.values:array"],"optional":["exhibitNo","chart.type","chart.series:array","chart.points:array","chart.max","chart.unit","chart.colors:array","chart.dataTable","note"]},"twocol":{"label":"双栏论证页(research R1)","modes":["research"],"required":["paragraphs:array"]},"threecol":{"label":"三栏证据页(research R6)","modes":["research"],"required":["paragraphs:array"]},"halftable":{"label":"半表半图页(research R7)","modes":["research"],"required":["table.head:array","table.rows:array","chart.labels:array","chart.values:array"],"optional":["table.colW:array","chart.type","chart.series:array","chart.points:array","chart.max","chart.unit","chart.colors:array","chart.dataTable","note"]},"matrix":{"label":"矩阵图页(research R8)","modes":["research"],"required":["rowHeads:array","colHeads:array","cells:array"]},"lane":{"label":"泳道页(architecture A2)","modes":["architecture"],"required":["lanes:array"]},"sankey":{"label":"桑基图页(节点-流带,流向与流量)","modes":["research","architecture"],"required":["flows:array"],"optional":["unit","chart.dataTable","note"]},"treemap":{"label":"树图页(面积编码的层级构成)","modes":["research","architecture"],"required":["items:array"],"optional":["unit","chart.dataTable","note"]},"boxplot":{"label":"箱线图页(分布对比:min/q1/median/q3/max)","modes":["research","architecture"],"required":["groups:array"],"optional":["unit","chart.dataTable","note"]},"network":{"label":"关系网络页(节点-边拓扑)","modes":["research","architecture"],"required":["nodes:array","edges:array"],"optional":["chart.dataTable","note"]},"marimekko":{"label":"马赛克图页(列宽 × 列高双重编码)","modes":["research","architecture"],"required":["cols:array","cells:array"],"optional":["unit","chart.dataTable","note"]},"streamgraph":{"label":"流带图页(时间上的构成演变)","modes":["research","architecture"],"required":["series:array"],"optional":["labels:array","chart.dataTable","note"]}}};
|
|
2217
2246
|
/* __TOPPPT_SCHEMA_END__ */
|
|
2218
2247
|
|
|
2219
2248
|
var _mode = 'presentation'; /* 当前模式(slidesOf 里按 model.mode 设置) */
|
|
@@ -2504,6 +2533,15 @@ function footnoteLine(sh, text, S) {
|
|
|
2504
2533
|
sh.push(txSp(R.x, R.y, R.w, R.h,
|
|
2505
2534
|
[[{ t: text, sz: 9.5, col: S.faint, font: S.font }]]));
|
|
2506
2535
|
}
|
|
2536
|
+
/* R2:sec.note 与 sec.footnote 共用注释带末行(footnoteY=6.72)。
|
|
2537
|
+
note.y=6.55 会压进 so-what 带(6.05–6.67)——同页二者必须合并为一行。 */
|
|
2538
|
+
function noteOrFootnote(sh, sec, S) {
|
|
2539
|
+
var parts = [];
|
|
2540
|
+
if (sec && sec.note) parts.push(String(sec.note));
|
|
2541
|
+
if (sec && sec.footnote) parts.push(String(sec.footnote));
|
|
2542
|
+
if (!parts.length) return;
|
|
2543
|
+
footnoteLine(sh, parts.join(' · '), S);
|
|
2544
|
+
}
|
|
2507
2545
|
/* 待核实清单条(accent 强调色标注 · 与 build_pptx.js / HTML .flagbar 同源) */
|
|
2508
2546
|
function flagBar(sh, items, S, yTop) {
|
|
2509
2547
|
var F = PT.flagbar || { hdH: 0.26, rowH: 0.24, maxRows: 3, gap: 0.12 };
|
|
@@ -2692,7 +2730,9 @@ function vbarShapes(sh, ec, S, x, y, w, h, dcols) {
|
|
|
2692
2730
|
: [{ name: '数值', values: ec.values || [] }];
|
|
2693
2731
|
var nb = Math.max(1, labels.length);
|
|
2694
2732
|
var ns = Math.max(1, series.length);
|
|
2695
|
-
|
|
2733
|
+
/* R2:类目标签带必须含在 h 内(原 baseY+0.08 画在图区外,会压进 so-what/来源行) */
|
|
2734
|
+
var labelH = 0.36;
|
|
2735
|
+
var baseY = y + Math.max(0.6, h - labelH), plotW = w, step = plotW / nb;
|
|
2696
2736
|
var cluster = Math.min(1.1, step * (ns > 1 ? 0.78 : 0.55));
|
|
2697
2737
|
var bw = cluster / ns;
|
|
2698
2738
|
var all = [];
|
|
@@ -2701,26 +2741,27 @@ function vbarShapes(sh, ec, S, x, y, w, h, dcols) {
|
|
|
2701
2741
|
});
|
|
2702
2742
|
var vmax = ec.max || Math.max.apply(null, all.concat([1]));
|
|
2703
2743
|
var top = all.length ? Math.max.apply(null, all) : 0;
|
|
2744
|
+
var plotH = Math.max(0.35, baseY - y);
|
|
2704
2745
|
sh.push(shape('rect', x, baseY, plotW, 0.02, S.line));
|
|
2705
2746
|
series.forEach(function (se, si) {
|
|
2706
2747
|
var vals = se.values || [];
|
|
2707
2748
|
var col = dcols ? dcols[si % 5] : (si === 0 ? S.accent : S.faint);
|
|
2708
2749
|
vals.forEach(function (v, i) {
|
|
2709
2750
|
var num = Number(v) || 0;
|
|
2710
|
-
var hh = Math.max(0.05, num / vmax * (
|
|
2751
|
+
var hh = Math.max(0.05, num / vmax * (plotH - 0.35));
|
|
2711
2752
|
var bx = x + i * step + (step - cluster) / 2 + si * bw;
|
|
2712
2753
|
var hot = ns === 1 && num === top;
|
|
2713
2754
|
sh.push(shape('roundRect', bx, baseY - hh, Math.max(0.04, bw * 0.92), hh,
|
|
2714
2755
|
hot ? (dcols ? dcols[i % 5] : S.accent) : col, { adj: 6000 }));
|
|
2715
2756
|
if (ns === 1) {
|
|
2716
|
-
sh.push(txSp(bx - 0.3, baseY - hh - 0.
|
|
2757
|
+
sh.push(txSp(bx - 0.3, baseY - hh - 0.36, bw + 0.6, 0.30,
|
|
2717
2758
|
[[{ t: valText(num, ec.unit), sz: 12.5, b: 1, col: hot ? S.accent : S.body, font: S.font }]], { align: 'ctr' }));
|
|
2718
2759
|
}
|
|
2719
2760
|
});
|
|
2720
2761
|
});
|
|
2721
2762
|
labels.forEach(function (lb, i) {
|
|
2722
2763
|
var lx = x + i * step;
|
|
2723
|
-
sh.push(txSp(lx, baseY + 0.
|
|
2764
|
+
sh.push(txSp(lx, baseY + 0.06, step, labelH - 0.08,
|
|
2724
2765
|
[[{ t: lb, sz: 10.5, col: S.faint, font: S.font }]], { align: 'ctr' }));
|
|
2725
2766
|
});
|
|
2726
2767
|
/* Multi-series legend along top of plot (keeps category labels; avoids blank chart). */
|
|
@@ -2743,7 +2784,10 @@ function lineShapes(sh, ec, S, x, y, w, h, dcols) {
|
|
|
2743
2784
|
var all = [];
|
|
2744
2785
|
series.forEach(function (se) { (se.values || []).forEach(function (v) { all.push(Number(v) || 0); }); });
|
|
2745
2786
|
var vmax = ec.max || Math.max.apply(null, all.concat([1]));
|
|
2746
|
-
|
|
2787
|
+
/* R2:类目标签带含在 h 内,禁画到图区外压 so-what */
|
|
2788
|
+
var labelH = 0.36;
|
|
2789
|
+
var baseY = y + Math.max(0.6, h - labelH);
|
|
2790
|
+
var plotH = Math.max(0.35, baseY - y - 0.2);
|
|
2747
2791
|
sh.push(shape('rect', x, baseY, w, 0.02, S.line));
|
|
2748
2792
|
var stepX = n > 1 ? w / (n - 1) : 0;
|
|
2749
2793
|
series.forEach(function (se, si) {
|
|
@@ -2763,7 +2807,7 @@ function lineShapes(sh, ec, S, x, y, w, h, dcols) {
|
|
|
2763
2807
|
});
|
|
2764
2808
|
labels.forEach(function (lb, i) {
|
|
2765
2809
|
var px = x + (n > 1 ? i * stepX : w / 2);
|
|
2766
|
-
sh.push(txSp(px - 0.5, baseY + 0.
|
|
2810
|
+
sh.push(txSp(px - 0.5, baseY + 0.06, 1.0, labelH - 0.08,
|
|
2767
2811
|
[[{ t: lb, sz: 10.5, col: S.faint, font: S.font }]], { align: 'ctr' }));
|
|
2768
2812
|
});
|
|
2769
2813
|
}
|
|
@@ -3215,25 +3259,44 @@ function slidesOf(model, S) {
|
|
|
3215
3259
|
c.push(txSp(MX, CV.subtitleY, CW - 1, CV.subtitleH, [[{ t: model.subtitle || '', sz: 18, col: S.soft, font: S.font }]]));
|
|
3216
3260
|
slides.push(c);
|
|
3217
3261
|
|
|
3218
|
-
/* Agenda(>8
|
|
3262
|
+
/* Agenda(>8 条自动双列;>12 条自动分页;长标题截断+全称入 notes;列优先与 HTML 一致) */
|
|
3219
3263
|
var items = model.agenda || [];
|
|
3220
3264
|
if (items.length) {
|
|
3221
|
-
var
|
|
3222
|
-
|
|
3223
|
-
var
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
var
|
|
3230
|
-
var
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3265
|
+
var ROWS_PER_PAGE = 12;
|
|
3266
|
+
var agPages = [];
|
|
3267
|
+
for (var ai = 0; ai < items.length; ai += ROWS_PER_PAGE) agPages.push(items.slice(ai, ai + ROWS_PER_PAGE));
|
|
3268
|
+
agPages.forEach(function (pageItems, pi) {
|
|
3269
|
+
var ag = [];
|
|
3270
|
+
var sub = agPages.length > 1 ? '(' + (pi + 1) + '/' + agPages.length + ')' : '';
|
|
3271
|
+
head(ag, 'AGENDA', '报告大纲' + sub);
|
|
3272
|
+
var colN = pageItems.length > 8 ? 2 : 1;
|
|
3273
|
+
var perCol = Math.ceil(pageItems.length / colN) || 1;
|
|
3274
|
+
var rowH = Math.min(1.05, (CONTENT_BOTTOM - CONTENT_TOP - 0.25) / Math.max(1, perCol));
|
|
3275
|
+
var numSz = rowH >= 0.85 ? 30 : (rowH >= 0.65 ? 22 : 18);
|
|
3276
|
+
var tSz = rowH >= 0.85 ? 16 : 14, dSz = rowH >= 0.85 ? 12 : 11;
|
|
3277
|
+
var agNotes = [];
|
|
3278
|
+
pageItems.forEach(function (it, i) {
|
|
3279
|
+
var col = Math.floor(i / perCol), row = i % perCol;
|
|
3280
|
+
var x = MX + col * (CW / colN), y = CONTENT_TOP + row * rowH;
|
|
3281
|
+
var titleBoxW = CW / colN - 1.15;
|
|
3282
|
+
var rawTitle = String(it[1] || '');
|
|
3283
|
+
var titleEstW = estTextH(rawTitle, titleBoxW, tSz, 1.2);
|
|
3284
|
+
var maxTitleH = rowH * 0.55;
|
|
3285
|
+
var title = rawTitle;
|
|
3286
|
+
if (titleEstW > maxTitleH) {
|
|
3287
|
+
var maxChars = Math.max(10, Math.floor(rawTitle.length * (maxTitleH / titleEstW)));
|
|
3288
|
+
if (rawTitle.length > maxChars) {
|
|
3289
|
+
title = rawTitle.slice(0, maxChars - 1) + '…';
|
|
3290
|
+
agNotes.push('条目 ' + it[0] + ' 全称:' + rawTitle);
|
|
3291
|
+
}
|
|
3292
|
+
}
|
|
3293
|
+
ag.push(txSp(x, y, 0.9, Math.min(0.9, rowH), [[{ t: it[0], sz: numSz, b: 1, col: S.accent, font: S.font }]]));
|
|
3294
|
+
ag.push(txSp(x + 1.0, y + 0.03, titleBoxW, Math.min(0.95, rowH),
|
|
3295
|
+
[[{ t: title, sz: tSz, b: 1, col: S.ink, font: S.font }],
|
|
3296
|
+
[{ t: it[2] || '', sz: dSz, col: S.body, font: S.font }]], { lineSpacing: tSz + 5 }));
|
|
3297
|
+
});
|
|
3298
|
+
slides.push(ag);
|
|
3235
3299
|
});
|
|
3236
|
-
slides.push(ag);
|
|
3237
3300
|
}
|
|
3238
3301
|
|
|
3239
3302
|
/* 章节页 */
|
|
@@ -3319,12 +3382,13 @@ function slidesOf(model, S) {
|
|
|
3319
3382
|
{ t: p[1], sz: fz - 1, col: S.body, font: S.font }]]));
|
|
3320
3383
|
});
|
|
3321
3384
|
});
|
|
3385
|
+
/* R2:verdict 与 soWhat 共用 annotation 槽位——只画一个(verdict 优先) */
|
|
3322
3386
|
if (sec.verdict) {
|
|
3323
3387
|
var vR = regOf('exhibit', 'annotation') || { x: MX, y: PT.exhibit.soWhatY, w: CW, h: 0.62 };
|
|
3324
|
-
sh.push(shape('rect', vR.x, vR.y, vR.w, vR.h, S.accent));
|
|
3388
|
+
sh.push(shape('rect', vR.x, vR.y, vR.w, vR.h, S.accent, { name: 'tr:soWhat' }));
|
|
3325
3389
|
sh.push(txSp(vR.x + 0.22, vR.y + 0.06, vR.w - 0.44, vR.h - 0.12,
|
|
3326
3390
|
[[{ t: '结论 ', sz: 11, b: 1, col: S.onAccent, font: S.font, spc: 150 },
|
|
3327
|
-
{ t: sec.verdict, sz: 12.5, b: 1, col: S.onAccent, font: S.font }]], { anchor: 'ctr' }));
|
|
3391
|
+
{ t: sec.verdict, sz: 12.5, b: 1, col: S.onAccent, font: S.font }]], { anchor: 'ctr', name: 'tr:soWhat' }));
|
|
3328
3392
|
}
|
|
3329
3393
|
} else if (type === 'quote') {
|
|
3330
3394
|
var Q = PT.quote;
|
|
@@ -3357,7 +3421,6 @@ function slidesOf(model, S) {
|
|
|
3357
3421
|
} else if (type === 'donut') {
|
|
3358
3422
|
var dcn = sec.chart || {};
|
|
3359
3423
|
if (dcn.labels && dcn.values) donutChart(sh, dcn, S, dcn.colors || donutColors(model.style, S, model.theme), bodyBottom);
|
|
3360
|
-
if (sec.note) sh.push(txSp(MX, PT.note.y, CW, PT.note.h, [[{ t: sec.note, sz: 11, col: S.faint, font: S.font }]]));
|
|
3361
3424
|
} else if (type === 'heatmap') {
|
|
3362
3425
|
var H = PT.heatmap;
|
|
3363
3426
|
var hR = regOf('heatmap', 'primary', { bottom: bodyBottom }) || { x: MX, y: H.y, w: CW, h: bodyBottom - H.y };
|
|
@@ -3504,7 +3567,7 @@ function slidesOf(model, S) {
|
|
|
3504
3567
|
} else if (type === 'bar') {
|
|
3505
3568
|
var ch = sec.chart || {};
|
|
3506
3569
|
var dcols2 = (ch.colors || dataColors(model.style, model.theme));
|
|
3507
|
-
var botY = chartBottom(!!sec.soWhat, !!sec.footnote
|
|
3570
|
+
var botY = chartBottom(!!sec.soWhat, !!(sec.footnote || sec.note)) - 0.05;
|
|
3508
3571
|
var isHBar = ch.type === 'hbar';
|
|
3509
3572
|
var bRR = regOf('bar', isHBar ? 'hbar' : 'primary', { bottom: botY }) ||
|
|
3510
3573
|
{ x: isHBar ? MX : MX + PT.bar.chartX, y: isHBar ? PT.bar.hbarY0 : PT.bar.chartY,
|
|
@@ -3531,13 +3594,12 @@ function slidesOf(model, S) {
|
|
|
3531
3594
|
} else {
|
|
3532
3595
|
chartBlockShapes(sh, ch, S, bx, bRR.y, bw, Math.max(1.5, bRR.h), dcols2);
|
|
3533
3596
|
}
|
|
3534
|
-
if (sec.note) sh.push(txSp(MX, PT.note.y, CW, PT.note.h, [[{ t: sec.note, sz: 11, col: S.faint, font: S.font }]]));
|
|
3535
3597
|
} else if (type === 'twocol' || type === 'threecol') {
|
|
3536
3598
|
var ps2 = sec.paragraphs || [];
|
|
3537
3599
|
var nCol = (type === 'threecol') ? 3 : 2;
|
|
3538
3600
|
var gapC = (type === 'threecol') ? PT.research.col3Gap : PT.twocol.colGap;
|
|
3539
|
-
|
|
3540
|
-
|
|
3601
|
+
/* R3:多栏均分用版心全宽(regOf('twocol') 返回单栏宽,当总宽会压扁三栏) */
|
|
3602
|
+
var tcR = { x: MX, y: bodyY, w: CW, h: bodyBottom - bodyY };
|
|
3541
3603
|
var gC = cols(tcR.w, nCol, gapC);
|
|
3542
3604
|
var perC = Math.ceil(ps2.length / nCol);
|
|
3543
3605
|
var availC = tcR.h;
|
|
@@ -3733,7 +3795,7 @@ function slidesOf(model, S) {
|
|
|
3733
3795
|
var dStart = dgR.y;
|
|
3734
3796
|
var dEnd = dgR.y + dgR.h;
|
|
3735
3797
|
var nLay = Math.max(1, lys.length);
|
|
3736
|
-
var lh2 = Math.max(0.
|
|
3798
|
+
var lh2 = Math.max(0.5, Math.min(D.maxLayerH, (dEnd - dStart) / nLay - D.layerGap));
|
|
3737
3799
|
lys.forEach(function (lay, li) {
|
|
3738
3800
|
var y9 = dStart + li * (lh2 + D.layerGap);
|
|
3739
3801
|
var focus = lay[2] === 'focus';
|
|
@@ -3749,9 +3811,26 @@ function slidesOf(model, S) {
|
|
|
3749
3811
|
var ntt = isRec(nd) ? nd.t : nd;
|
|
3750
3812
|
var nds = isRec(nd) ? (nd.d || '') : '';
|
|
3751
3813
|
sh.push(shape('roundRect', x10, y9, nw2, lh2, ndacc ? S.soft : S.surface, { adj: 4000, line: S.line }));
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3814
|
+
/* R1: 注解不得「浮回」标题上。标题顶对齐,注解钳在标题下边;空间不足降级单框混排。 */
|
|
3815
|
+
var padXn = 0.12, padYn = 0.10;
|
|
3816
|
+
var innerWn = nw2 - padXn * 2;
|
|
3817
|
+
var titleHn = 0.32, noteHn = 0.34, gapTNn = 0.04;
|
|
3818
|
+
var needHn = titleHn + gapTNn + (nds ? noteHn : 0) + padYn * 2;
|
|
3819
|
+
if (!nds || lh2 >= needHn) {
|
|
3820
|
+
var tYn = y9 + padYn;
|
|
3821
|
+
sh.push(txSp(x10 + padXn, nds ? tYn : y9 + lh2 / 2 - 0.18, innerWn, titleHn,
|
|
3822
|
+
[[{ t: ntt, sz: nds ? 11 : 12.5, b: 1, col: ndacc ? S.accent : S.ink, font: S.font }]],
|
|
3823
|
+
{ anchor: 'ctr' }));
|
|
3824
|
+
if (nds) {
|
|
3825
|
+
var nYn = Math.max(tYn + titleHn + gapTNn, y9 + lh2 - padYn - noteHn);
|
|
3826
|
+
sh.push(txSp(x10 + padXn, nYn, innerWn, Math.min(noteHn, y9 + lh2 - padYn - nYn),
|
|
3827
|
+
[[{ t: nds, sz: 10, col: S.faint, font: S.font }]], { anchor: 't' }));
|
|
3828
|
+
}
|
|
3829
|
+
} else {
|
|
3830
|
+
sh.push(txSp(x10 + padXn, y9 + padYn * 0.5, innerWn, lh2 - padYn,
|
|
3831
|
+
[[{ t: ntt, sz: 11, b: 1, col: ndacc ? S.accent : S.ink, font: S.font }],
|
|
3832
|
+
[{ t: nds, sz: 9, col: S.faint, font: S.font }]], { anchor: 't', lineSpacing: 12 }));
|
|
3833
|
+
}
|
|
3755
3834
|
});
|
|
3756
3835
|
if (li < lys.length - 1) {
|
|
3757
3836
|
var cy2 = y9 + lh2 + D.layerGap / 2;
|
|
@@ -3761,10 +3840,14 @@ function slidesOf(model, S) {
|
|
|
3761
3840
|
}
|
|
3762
3841
|
});
|
|
3763
3842
|
if (sec.legend) {
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3843
|
+
/* R2:图例进图区底部(与 HTML .arch__legend 同源),禁用 PH-0.62 固定偏移 */
|
|
3844
|
+
var lgH2 = 0.28;
|
|
3845
|
+
var lgY2 = Math.max(dStart, bodyBottom - lgH2 - 0.02);
|
|
3846
|
+
var nLg2 = Math.max(1, sec.legend.length);
|
|
3847
|
+
var step2 = Math.min(2.4, CW / nLg2);
|
|
3848
|
+
sec.legend.forEach(function (lg2, li2) {
|
|
3849
|
+
sh.push(txSp(MX + CW - nLg2 * step2 + li2 * step2, lgY2, step2 - 0.05, lgH2,
|
|
3850
|
+
[[{ t: '● ' + lg2, sz: 10, col: S.faint, font: S.font }]]));
|
|
3768
3851
|
});
|
|
3769
3852
|
}
|
|
3770
3853
|
} else if (type === 'exhibit') {
|
|
@@ -3821,8 +3904,10 @@ function slidesOf(model, S) {
|
|
|
3821
3904
|
}
|
|
3822
3905
|
}
|
|
3823
3906
|
/* research 通用可选件:so-what 结论条 + 页脚来源行 + 待核实条(共用同一槽位) */
|
|
3824
|
-
|
|
3825
|
-
if (sec.
|
|
3907
|
+
/* R2:verdict 已占 annotation 槽位时跳过 soWhat,禁止同槽双条叠印 */
|
|
3908
|
+
if (sec.soWhat && !sec.verdict) soWhatBar(sh, sec.soWhat, S);
|
|
3909
|
+
/* R2:note 与 footnote 共用注释带末行(禁 note.y=6.55 压 so-what) */
|
|
3910
|
+
noteOrFootnote(sh, sec, S);
|
|
3826
3911
|
if (flagH) flagBar(sh, flagItems, S, flagY);
|
|
3827
3912
|
slides.push(sh);
|
|
3828
3913
|
});
|
|
@@ -3992,9 +4077,10 @@ function validateModel(model) {
|
|
|
3992
4077
|
}
|
|
3993
4078
|
var agMax = (M.model && M.model.agendaComfortMax) || 16;
|
|
3994
4079
|
if ((model.agenda || []).length > agMax) {
|
|
3995
|
-
warnings.push('agenda ' + model.agenda.length + ' 条超出单页舒适上限 ' + agMax + '
|
|
4080
|
+
warnings.push('agenda ' + model.agenda.length + ' 条超出单页舒适上限 ' + agMax + ',将自动分页');
|
|
3996
4081
|
}
|
|
3997
|
-
var
|
|
4082
|
+
var agPageCount = hasAgenda ? Math.ceil(model.agenda.length / 12) : 0;
|
|
4083
|
+
var pages = 1 + agPageCount + secs.length + 1; /* 封面+大纲(可多页)+章节+收尾 */
|
|
3998
4084
|
return { ok: missing.length === 0, missing: missing, warnings: warnings, pages: pages };
|
|
3999
4085
|
}
|
|
4000
4086
|
|