lactic-ch1-challenge.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. // ==============================================================================
  2. // 江中乳酸菌素片儿童版 · Ch1 诘问起点(3 子章)
  3. // ==============================================================================
  4. // 1.1 现状困境·6000万规模 × 0 差异化
  5. // 1.2 10亿目标·药品/食品/软糖三轴破局
  6. // 1.3 VOC 反向验证·家长 × 儿童双视角起点
  7. // ==============================================================================
  8. const LA = require('./lactic-analyze.js');
  9. const C = require('./lactic-components.js');
  10. const { BRAND, esc, fmtLikes } = C;
  11. // ==========================================================
  12. // 1.1 · 现状困境·成人版爆款但儿童版零心智
  13. // ==========================================================
  14. function renderSub1_1(ctx) {
  15. const { chapter: c, subIdx, sub, slideNum, slideTotal, data } = ctx;
  16. const items = data.items || [];
  17. // 证据 A:乳酸菌素片(成人)已经有爆款 VOC "肠鸣就这样好了"
  18. const adultHit = LA.getEvidence(items, {
  19. keyword: '乳酸菌素片',
  20. contentMatch: /肠鸣|胃胀|神药|便秘|好了|有用|治好|咕噜/,
  21. minChars: 20, top: 4, seed: 7,
  22. });
  23. // 证据 B:乳酸菌素片儿童关键词数据稀薄 = 儿童版心智真空
  24. const childWeak = LA.getEvidence(items, {
  25. keyword: '乳酸菌素片儿童',
  26. minChars: 15, top: 3, seed: 11,
  27. });
  28. // 证据 C:家长在妈咪爱/合生元之间选,不会想起乳酸菌素片
  29. const momiParent = LA.getEvidence(items, {
  30. keyword: '妈咪爱',
  31. contentMatch: /宝宝|孩子|儿童|胀气|月子|月龄|岁/,
  32. minChars: 25, top: 3, seed: 13,
  33. });
  34. return `<section class="report-section" id="${c.key}-${subIdx}" data-tone="${c.tone}" data-slide-num="${slideNum}/${slideTotal}">
  35. <div class="section-inner">
  36. ${C.renderSectionHead({
  37. eyebrow: `${c.num}.${subIdx} · 现状困境直面`,
  38. title: '成人版握有 <span style="color:' + BRAND.LACTIC_MINT + ';">"肠鸣神药" 爆款认知</span>,但儿童版<span style="color:' + BRAND.CORAL + ';">零心智</span>',
  39. subtitle: '乳酸菌素片<strong>成人版</strong>在小红书/抖音有<strong>万赞级爆款</strong>("肠鸣就这样好了" ♥4848、"一根那啥通大脑" ♥62890),但<strong>儿童版关键词 ≤ ♥40</strong>—— 不是品类不火,是<strong>儿童专属心智没建立起来</strong>。',
  40. color: BRAND.CORAL,
  41. })}
  42. ${C.renderInsightHero({
  43. eyebrow: 'THE REAL GAP · 核心落差',
  44. color: BRAND.CORAL,
  45. title: `成人版"<strong>肠鸣神药</strong>"——抖音爆款 <strong style="color:${BRAND.LACTIC_MINT};">♥62,890</strong>;儿童版最高赞 <strong style="color:${BRAND.CORAL};">♥40</strong>。<br/>这不是品牌不行,是<strong style="color:${BRAND.CORAL};">儿童版根本没被作为独立产品运营过</strong>——只是给成人版加了个娃娃头。`,
  46. subtitle: `与此同时<strong style="color:${BRAND.TECH_BLUE};">妈咪爱</strong>单条抖音视频获 <strong style="color:${BRAND.TECH_BLUE};">♥33,099</strong>("为了口吃的费尽了心思")、<strong style="color:${BRAND.SUNNY_YELLOW};">合生元</strong>"亲测有效"抖音 <strong style="color:${BRAND.SUNNY_YELLOW};">♥10,191</strong>——竞品在儿童家长心里已经<strong>有名有姓有故事</strong>。`,
  47. })}
  48. ${C.renderStatStrip([
  49. { num: '6000万', label: '乳酸菌素片儿童线下', color: BRAND.CORAL },
  50. { num: '400-500万', label: '乳酸菌素片儿童线上', color: BRAND.CORAL },
  51. { num: '3.6亿', label: '妈咪爱线下(对标)', color: BRAND.TECH_BLUE },
  52. { num: '3848万', label: '妈咪爱线上(对标)', color: BRAND.TECH_BLUE },
  53. { num: '100亿+', label: '儿童营养软糖赛道', color: BRAND.SUNNY_YELLOW, delta: '可迁移' },
  54. ], { accent: BRAND.CORAL })}
  55. <div class="grid" style="grid-template-columns:1fr 1fr; gap:24px; margin-top:24px;">
  56. <div>
  57. <div class="text-mono text-xs" style="color:${BRAND.LACTIC_MINT}; letter-spacing:0.18em; margin-bottom:14px; font-weight:700;">VOC · 成人版已经有的爆款心智</div>
  58. <div style="display:flex; flex-direction:column; gap:12px;">
  59. ${adultHit.slice(0, 3).map((it) => C.renderVocCard(it, { accent: BRAND.LACTIC_MINT, compact: true, maxChars: 180 })).join('')}
  60. </div>
  61. </div>
  62. <div>
  63. <div class="text-mono text-xs" style="color:${BRAND.CORAL}; letter-spacing:0.18em; margin-bottom:14px; font-weight:700;">VOC · 儿童版的真空状态</div>
  64. <div style="display:flex; flex-direction:column; gap:12px;">
  65. ${childWeak.slice(0, 3).map((it) => C.renderVocCard(it, { accent: BRAND.CORAL, compact: true, maxChars: 180 })).join('')}
  66. </div>
  67. </div>
  68. </div>
  69. <div class="fade-up" style="margin-top:28px;">
  70. ${C.renderCompareTable({
  71. title: 'GAP · 成人版真相 vs 儿童版幻觉',
  72. headers: ['对比维度', '成人版(已验证)', '儿童版(幻觉现状)'],
  73. rows: [
  74. ['爆款 VOC', { html: `<strong style="color:${BRAND.LACTIC_MINT};">♥62,890 / ♥4,848 / ♥16,144</strong>`, color: BRAND.LACTIC_MINT, bold: true }, { html: `<strong style="color:${BRAND.CORAL};">最高 ♥40 · 零爆款</strong>`, color: BRAND.CORAL, bold: true }],
  75. ['用户心智', { html: `"肠鸣神药"/"胃胀就吃这个"`, color: BRAND.LACTIC_MINT }, { html: `"不知道是给大人还是小孩的"`, color: BRAND.CORAL }],
  76. ['场景描述', { html: `自习室/办公室/外卖后`, color: BRAND.LACTIC_MINT }, { html: `——(几乎没有场景 VOC)`, color: BRAND.CORAL }],
  77. ['产品差异', { html: `乳酸菌素 0.4g / 片剂 0.8g`, color: BRAND.SAGE }, { html: `乳酸菌素 0.2g / 片剂 0.5g`, color: BRAND.SAGE }],
  78. ['包装差异', { html: `标准药盒 + 药品严肃感`, color: BRAND.SAGE }, { html: `<strong>仅加"娃娃头"</strong>`, color: BRAND.CORAL, bold: true }],
  79. ['说明书差异', { html: `成人用法 0.8g × 3次/日`, color: BRAND.SAGE }, { html: `<strong>与成人版一模一样</strong>`, color: BRAND.CORAL, bold: true }],
  80. ['家长选择路径', { html: '—(不是决策者)', color: 'var(--text-3)' }, { html: `<strong>妈咪爱 → 合生元 → (乳酸菌素片?)</strong>`, color: BRAND.CORAL, bold: true }],
  81. ['破局', { html: '不需要破局', color: BRAND.LACTIC_MINT, bold: true }, { html: '必须重新定位 × VOC 反向验证', color: BRAND.CORAL, bold: true }],
  82. ],
  83. accent: BRAND.CORAL,
  84. })}
  85. </div>
  86. ${C.renderDecisionList([
  87. `<strong>直面"娃娃头困境"</strong>:不再把儿童当"成人减量版",必须独立品牌叙事`,
  88. `<strong>迁移成人爆款心智</strong>:把"肠鸣神药"翻译成儿童话术"肚子小魔法"`,
  89. `<strong>承认竞品领先</strong>:妈咪爱/合生元先发心智,乳酸菌素片必须从细分场景切入`,
  90. `<strong>反向定位先于产品升级</strong>:先用 VOC 找家长真实需求,再决定 SKU / 包装 / 话术`,
  91. ], { title: '落地决策 · 诘问起点 4 条铁律', accent: BRAND.CORAL, columns: 2 })}
  92. </div>
  93. </section>`;
  94. }
  95. // ==========================================================
  96. // 1.2 · 10亿目标·药品/食品/软糖三轴破局
  97. // ==========================================================
  98. function renderSub1_2(ctx) {
  99. const { chapter: c, subIdx, sub, slideNum, slideTotal, data } = ctx;
  100. const items = data.items || [];
  101. // H1 药品益生菌痛点代表 VOC
  102. const drugPain = LA.getEvidence(items, {
  103. hypothesis: 'H1',
  104. contentMatch: /冷藏|冷链|处方|医生开|停药|反弹|依赖|贵/,
  105. minChars: 25, top: 2, seed: 5,
  106. });
  107. // H2 食品益生菌矛盾代表 VOC
  108. const foodDoubt = LA.getEvidence(items, {
  109. hypothesis: 'H2',
  110. contentMatch: /没效果|智商税|食品级|八十|不确定/,
  111. minChars: 25, top: 2, seed: 7,
  112. });
  113. // 瓶瓶罐罐焦虑(H7,如果有)
  114. const tooManyBottles = LA.getEvidence(items, {
  115. contentMatch: /瓶瓶罐罐|各种营养|追着喂|一堆|十几种|补不了/,
  116. minChars: 20, top: 2, seed: 11,
  117. });
  118. return `<section class="report-section" id="${c.key}-${subIdx}" data-tone="${c.tone}" data-slide-num="${slideNum}/${slideTotal}">
  119. <div class="section-inner">
  120. ${C.renderSectionHead({
  121. eyebrow: `${c.num}.${subIdx} · 10 亿目标路径`,
  122. title: '三轴破局 · <span style="color:' + BRAND.TECH_BLUE + ';">药品益生菌</span> ↔ <span style="color:' + BRAND.SUNNY_YELLOW + ';">食品益生菌</span> ↔ <span style="color:' + BRAND.BERRY_PINK + ';">营养软糖</span>',
  123. subtitle: '乳酸菌素片儿童版<strong>不是单一赛道的挑战者</strong>,而是<strong>跨 3 条赛道的新品类</strong>——OTC 合规的安全壁垒 × 日常长期服用的便利 × 内源调理的吸收升级。',
  124. color: BRAND.JIANG_GREEN,
  125. })}
  126. <div class="grid" style="grid-template-columns:1fr 1fr 1fr; gap:18px; margin-top:24px;">
  127. <!-- 药品益生菌赛道 -->
  128. <div style="padding:20px 22px; background:${BRAND.TECH_BLUE}08; border:1px solid ${BRAND.TECH_BLUE}33; border-radius:var(--radius-md); border-top:4px solid ${BRAND.TECH_BLUE};">
  129. <div class="text-mono text-xs" style="color:${BRAND.TECH_BLUE}; letter-spacing:0.15em; font-weight:700; margin-bottom:6px;">AXIS 1 · 药品益生菌</div>
  130. <div style="color:var(--text-1); font-weight:800; font-size:1.1rem; margin-bottom:10px;">6 亿市场</div>
  131. <div style="color:var(--text-2); font-size:0.82rem; line-height:1.6; margin-bottom:12px;">
  132. 妈咪爱 3.6亿线下 + 3848万线上 · 亿活 / 金双岐 / 宝乐安<br/>
  133. <strong>痛点</strong>:活菌冷链麻烦 / 必须处方 / 停药反弹焦虑
  134. </div>
  135. ${drugPain[0] ? C.renderVocCard(drugPain[0], { accent: BRAND.TECH_BLUE, compact: true, maxChars: 140 }) : ''}
  136. <div style="margin-top:12px; padding:10px 12px; background:${BRAND.LACTIC_MINT}0A; border:1px solid ${BRAND.LACTIC_MINT}33; border-radius:4px;">
  137. <div class="text-mono text-xs" style="color:${BRAND.LACTIC_MINT}; font-weight:700; margin-bottom:4px;">切入点</div>
  138. <div style="color:var(--text-1); font-size:0.84rem;"><strong>非活菌常温稳定 × OTC 蓝帽子 × 可日常长期</strong></div>
  139. </div>
  140. </div>
  141. <!-- 食品益生菌赛道 -->
  142. <div style="padding:20px 22px; background:${BRAND.SUNNY_YELLOW}08; border:1px solid ${BRAND.SUNNY_YELLOW}33; border-radius:var(--radius-md); border-top:4px solid ${BRAND.SUNNY_YELLOW};">
  143. <div class="text-mono text-xs" style="color:${BRAND.SUNNY_YELLOW}; letter-spacing:0.15em; font-weight:700; margin-bottom:6px;">AXIS 2 · 食品益生菌</div>
  144. <div style="color:var(--text-1); font-weight:800; font-size:1.1rem; margin-bottom:10px;">20 亿市场</div>
  145. <div style="color:var(--text-2); font-size:0.82rem; line-height:1.6; margin-bottom:12px;">
  146. 合生元 / 万益蓝 / 拜奥 / inne / 小胖瓶 / 康萃乐 / lifespace<br/>
  147. <strong>痛点</strong>:无药品背书 / 菌株混乱 / "听八十个人说八十样"
  148. </div>
  149. ${foodDoubt[0] ? C.renderVocCard(foodDoubt[0], { accent: BRAND.SUNNY_YELLOW, compact: true, maxChars: 140 }) : ''}
  150. <div style="margin-top:12px; padding:10px 12px; background:${BRAND.LACTIC_MINT}0A; border:1px solid ${BRAND.LACTIC_MINT}33; border-radius:4px;">
  151. <div class="text-mono text-xs" style="color:${BRAND.LACTIC_MINT}; font-weight:700; margin-bottom:4px;">切入点</div>
  152. <div style="color:var(--text-1); font-size:0.84rem;"><strong>OTC 药品级背书 × 非活菌稳定 × 菌株明确</strong></div>
  153. </div>
  154. </div>
  155. <!-- 营养软糖赛道 -->
  156. <div style="padding:20px 22px; background:${BRAND.BERRY_PINK}08; border:1px solid ${BRAND.BERRY_PINK}33; border-radius:var(--radius-md); border-top:4px solid ${BRAND.BERRY_PINK};">
  157. <div class="text-mono text-xs" style="color:${BRAND.BERRY_PINK}; letter-spacing:0.15em; font-weight:700; margin-bottom:6px;">AXIS 3 · 儿童营养软糖</div>
  158. <div style="color:var(--text-1); font-weight:800; font-size:1.1rem; margin-bottom:10px;">100 亿+ 市场</div>
  159. <div style="color:var(--text-2); font-size:0.82rem; line-height:1.6; margin-bottom:12px;">
  160. 复合维生素软糖 + 钙软糖 + DHA 软糖 + 叶黄素软糖<br/>
  161. <strong>痛点</strong>:瓶瓶罐罐追着喂 / 糖分焦虑 / 补了还是不吸收
  162. </div>
  163. ${tooManyBottles[0] ? C.renderVocCard(tooManyBottles[0], { accent: BRAND.BERRY_PINK, compact: true, maxChars: 140 }) : `<div style="padding:12px; background:var(--bg-2); border-radius:4px; color:var(--text-3); font-size:0.8rem; text-align:center;">⌛ Batch 3 补充场景 VOC</div>`}
  164. <div style="margin-top:12px; padding:10px 12px; background:${BRAND.LACTIC_MINT}0A; border:1px solid ${BRAND.LACTIC_MINT}33; border-radius:4px;">
  165. <div class="text-mono text-xs" style="color:${BRAND.LACTIC_MINT}; font-weight:700; margin-bottom:4px;">切入点</div>
  166. <div style="color:var(--text-1); font-size:0.84rem;"><strong>内源调理肠道吸收 × 告别瓶瓶罐罐 × 1 片替代</strong></div>
  167. </div>
  168. </div>
  169. </div>
  170. <div class="fade-up" style="margin-top:28px;">
  171. ${C.renderInsightHero({
  172. eyebrow: 'REGIME CHANGE · 三轴交汇',
  173. color: BRAND.JIANG_GREEN,
  174. title: `单一赛道对标:<strong style="color:${BRAND.TECH_BLUE};">药品益生菌</strong> 就 3-5 亿,<strong style="color:${BRAND.SUNNY_YELLOW};">食品益生菌</strong> 做到头部也很难做 5 亿。<br/><strong style="color:${BRAND.JIANG_GREEN};">10 亿目标 = 3 轴叠加</strong>:基础盘(肠道调理)3-5 亿 + 增量盘(内源吸收)3-5 亿 + 溢价盘(分龄礼盒)1-2 亿。`,
  175. subtitle: `只在一个赛道里卷赢是死局——<strong>乳酸菌素片儿童版必须是"跨轴的新物种"</strong>。`,
  176. })}
  177. </div>
  178. ${C.renderDecisionList([
  179. `<strong>赛道一:肠道调理基础盘</strong> 3-5 亿 · 对标妈咪爱 × 非活菌差异化`,
  180. `<strong>赛道二:内源吸收增量盘</strong> 3-5 亿 · 告别瓶瓶罐罐 × 切入营养软糖市场`,
  181. `<strong>赛道三:分龄礼盒溢价盘</strong> 1-2 亿 · 送给婴幼儿 / 学龄前 / 学龄期 3 SKU`,
  182. `<strong>不单一赛道对标</strong>:必须同时踩稳 3 个脚 — "像药一样安全 × 像食品一样温和 × 像软糖一样爱吃"`,
  183. ], { title: '落地决策 · 三轴协同战术', accent: BRAND.JIANG_GREEN, columns: 2 })}
  184. </div>
  185. </section>`;
  186. }
  187. // ==========================================================
  188. // 1.3 · VOC 反向验证·家长 × 儿童双视角起点
  189. // ==========================================================
  190. function renderSub1_3(ctx) {
  191. const { chapter: c, subIdx, sub, slideNum, slideTotal, data, meta } = ctx;
  192. const H = LA.HYPOTHESES;
  193. const counts = meta?.hypotheses || {};
  194. return `<section class="report-section" id="${c.key}-${subIdx}" data-tone="${c.tone}" data-slide-num="${slideNum}/${slideTotal}">
  195. <div class="section-inner">
  196. ${C.renderSectionHead({
  197. eyebrow: `${c.num}.${subIdx} · 方法论起点`,
  198. title: '<span style="color:' + BRAND.LACTIC_MINT + ';">VOC 反向验证</span> × 家长 + 儿童 <span style="color:' + BRAND.BERRY_PINK + ';">双视角</span>',
  199. subtitle: '不做"创始人拍脑袋"的定位。从<strong>真实家长评论 + 儿童被观察反应</strong>反向倒推产品机会——这是本报告唯一的方法论起点。',
  200. color: BRAND.LACTIC_MINT,
  201. })}
  202. <div class="grid" style="grid-template-columns:1.2fr 1fr; gap:28px; margin-top:24px;">
  203. <div>
  204. <div class="text-mono text-xs" style="color:${BRAND.LACTIC_MINT}; letter-spacing:0.18em; margin-bottom:14px; font-weight:700;">8 大核心假设 H1-H8</div>
  205. <div style="display:flex; flex-direction:column; gap:10px;">
  206. ${Object.entries(H).map(([k, v]) => {
  207. const n = counts[k] || 0;
  208. const color = n > 300 ? BRAND.JIANG_GREEN : n > 50 ? BRAND.LACTIC_MINT : n > 0 ? BRAND.WARM_ORANGE : BRAND.CORAL;
  209. return `
  210. <div style="padding:12px 16px; background:var(--bg-1); border:1px solid var(--border); border-left:3px solid ${color}; border-radius:4px; display:grid; grid-template-columns:60px 1fr 80px; gap:12px; align-items:center;">
  211. <div style="color:${color}; font-family:var(--font-mono); font-weight:700; font-size:0.92rem;">${k}</div>
  212. <div>
  213. <div style="color:var(--text-1); font-weight:700; font-size:0.9rem;">${esc(v.title)}</div>
  214. <div style="color:var(--text-3); font-size:0.78rem; margin-top:2px;">${esc(v.desc)}</div>
  215. </div>
  216. <div style="text-align:right;">
  217. <div style="color:${color}; font-family:var(--font-mono); font-weight:700; font-size:1.05rem;">${n}</div>
  218. <div style="color:var(--text-3); font-size:0.68rem;">条 VOC</div>
  219. </div>
  220. </div>`;
  221. }).join('')}
  222. </div>
  223. </div>
  224. <div>
  225. ${C.renderTheoryBox({
  226. theory: '双视角 JTBD 框架',
  227. accent: BRAND.PURPLE,
  228. mapping: `
  229. <div style="display:flex; flex-direction:column; gap:12px; font-size:0.88rem;">
  230. <div style="padding:12px 14px; background:${BRAND.BERRY_PINK}0C; border-left:3px solid ${BRAND.BERRY_PINK}; border-radius:4px;">
  231. <div style="color:${BRAND.BERRY_PINK}; font-weight:700; margin-bottom:4px;">👩 家长 Job</div>
  232. <div style="color:var(--text-2); font-size:0.82rem; line-height:1.55;">决策买什么 · 心疼 · 怕出事 · 要专业感 · 能长期</div>
  233. </div>
  234. <div style="padding:12px 14px; background:${BRAND.SUNNY_YELLOW}0C; border-left:3px solid ${BRAND.SUNNY_YELLOW}; border-radius:4px;">
  235. <div style="color:${BRAND.SUNNY_YELLOW}; font-weight:700; margin-bottom:4px;">👶 儿童 Job</div>
  236. <div style="color:var(--text-2); font-size:0.82rem; line-height:1.55;">愿不愿意吃 · 好吃 · 不怕 · 有趣 · 被羡慕</div>
  237. </div>
  238. <div style="padding:12px 14px; background:${BRAND.JIANG_GREEN}0C; border-left:3px solid ${BRAND.JIANG_GREEN}; border-radius:4px;">
  239. <div style="color:${BRAND.JIANG_GREEN}; font-weight:700; margin-bottom:4px;">🎯 交汇点</div>
  240. <div style="color:var(--text-1); font-size:0.86rem; line-height:1.55; font-weight:600;">家长愿意买 × 孩子愿意吃 = 产品成立的<strong>唯一条件</strong></div>
  241. </div>
  242. </div>
  243. `,
  244. })}
  245. <div style="margin-top:18px;">
  246. ${C.renderFindingCard({
  247. icon: '🎯',
  248. title: 'VOC 数据透明度原则',
  249. accent: BRAND.LACTIC_MINT,
  250. body: `每条证据卡都带 <strong style="color:${BRAND.JIANG_GREEN};">✓ 真实采集</strong> 标识(来自 TikHub/VOC API 的真实小红书/抖音评论),附昵称 + IP + 点赞数 + 假设归类。<br/><br/>
  251. <strong>读者可以一眼验证</strong>:这是家长真说过的话,不是创始人想当然的"用户画像"。`,
  252. })}
  253. </div>
  254. </div>
  255. </div>
  256. ${C.renderDecisionList([
  257. `<strong>假设驱动而非灵感驱动</strong>:所有章节内容 = H1-H8 × 真实 VOC 交叉`,
  258. `<strong>家长决策链 + 儿童依从链 双重验证</strong>:缺一不可`,
  259. `<strong>反面教材优先</strong>:先看竞品差评(妈咪爱/合生元差评里找机会),再看本品好评`,
  260. `<strong>数据公开可复核</strong>:每条 VOC 带 nickname/IP/likes,杜绝"创始人说好"的空话`,
  261. ], { title: '落地决策 · 方法论自律', accent: BRAND.LACTIC_MINT, columns: 2 })}
  262. </div>
  263. </section>`;
  264. }
  265. module.exports = {
  266. 'challenge-1': renderSub1_1,
  267. 'challenge-2': renderSub1_2,
  268. 'challenge-3': renderSub1_3,
  269. };