import fs from 'node:fs/promises'; import path from 'node:path'; import {Presentation,PresentationFile} from '/Users/zhanghailin/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/@oai/artifact-tool/dist/artifact_tool.mjs'; process.env.RUNTIME_NODE_MODULES='/Users/zhanghailin/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules'; const BASE=path.resolve(process.argv[2]||new URL('..',import.meta.url).pathname); const SKILL='/Users/zhanghailin/.codex/plugins/cache/openai-primary-runtime/presentations/26.1026.10807/skills/presentations'; const PY='/Users/zhanghailin/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/bin/python3'; const C={ink:'#163D35',green:'#276450',mint:'#BDE6D1',lime:'#D9EDAC',white:'#FFFFFF',paper:'#F7FAF8',muted:'#60756D',line:'#D9E3DD',dark:'#102F29',amber:'#A86532',light:'#EAF3EE'}; const FONT='PingFang SC'; const OUTPUT_NAME=process.argv[3]||'知识库与腾讯ima教育应用培训-v2.pptx'; const p=Presentation.create({slideSize:{width:1280,height:720}}); const manifest=[]; function shape(s,g,x,y,w,h,fill,line='none',lw=0){return s.shapes.add({geometry:g,position:{left:x,top:y,width:w,height:h},fill,line:{fill:line,width:lw,style:'solid'}})} function text(s,t,x,y,w,h,size=26,color=C.ink,bold=false,align='left'){ const o=shape(s,'textbox',x,y,w,h,'none');o.text=t;o.text.style={fontFamily:FONT,typeface:FONT,fontSize:size,color,bold,alignment:align,verticalAlignment:'middle',wrap:true,insets:0};o.text.insets=0;return o; } function line(s,x,y,w,h,color=C.line,width=2){return s.shapes.add({geometry:'line',position:{left:Math.min(x,x+w),top:Math.min(y,y+h),width:Math.abs(w),height:Math.abs(h),horizontalFlip:w<0,verticalFlip:h<0},fill:'none',line:{fill:color,width,style:'solid'}})} function circle(s,x,y,d,fill){return shape(s,'ellipse',x,y,d,d,fill)} function tag(s,t,x,y,w=160,dark=false){shape(s,'roundRect',x,y,w,34,dark?'#254A3F':C.light);text(s,t,x+12,y+1,w-24,30,16,dark?C.mint:C.green,true)} function base(title,chapter,notes='',dark=false){ let s=p.slides.add();s.background.fill=dark?C.dark:C.paper; const n=p.slides.items.length;manifest.push({page:n,title:title||(n===1?'让教学资料用起来':'从一个单元开始'),chapter}); text(s,chapter,64,35,900,28,16,dark?C.mint:C.muted); if(title)text(s,title,64,89,1152,104,42,dark?C.white:C.ink,true); text(s,'知识库与腾讯 ima 教育应用',64,670,900,24,13,dark?'#AAC7BA':C.muted); text(s,String(n).padStart(2,'0')+' / 30',1116,670,100,24,14,dark?'#AAC7BA':C.muted,false,'right'); s.speakerNotes.text=notes;return s; } function note(s,t){s.speakerNotes.text += '\n'+t;} function rows(s,items,x=64,y=220,w=1100,gap=95){items.forEach((a,i)=>{text(s,String(i+1).padStart(2,'0'),x,y+i*gap,60,50,30,C.green,true);text(s,a[0],x+85,y+i*gap,w-85,44,28,C.ink,true);if(a[1])text(s,a[1],x+85,y+i*gap+43,w-85,42,21,C.muted);if(i{let x=64+i*(w+gap);text(s,String(i+1).padStart(2,'0'),x,y,w,80,58,dark?C.mint:C.green);text(s,a[0],x,y+106,w,58,29,dark?C.white:C.ink,true);text(s,a[1],x,y+182,w,Math.max(70,h-180),23,dark?'#C3D8CE':C.muted);});} function callout(s,t,y=591,dark=false){text(s,t,64,y,1152,48,23,dark?C.mint:C.green,true)} function table(s,headers,data,widths,{x=64,y=226,w=1152,h=330,size=22}={}){ const v=[headers,...data];let t=s.tables.add({rows:v.length,columns:headers.length,left:x,top:y,width:w,height:h,columnWidths:widths,values:v}); t.borders.assign({fill:C.line,width:1,style:'solid'}); v.forEach((r,ri)=>{t.rows[ri].height=h/v.length;}); v.forEach((r,ri)=>r.forEach((_,ci)=>{let c=t.getCell(ri,ci);c.fill=ri===0?C.green:(ri%2?C.white:C.light);c.text.style={fontFamily:FONT,typeface:FONT,fontSize:size,color:ri===0?C.white:C.ink,bold:ri===0,verticalAlignment:'middle',insets:14};}));return t; } function steps(s,items,y=255){const gap=30,w=(1152-(items.length-1)*gap)/items.length;items.forEach((a,i)=>{let x=64+i*(w+gap);circle(s,x,y,62,i===items.length-1?C.green:C.mint);text(s,''+(i+1),x,y,62,62,27,i===items.length-1?C.white:C.ink,true,'center');text(s,a[0],x,y+90,w,70,28,C.ink,true);text(s,a[1],x,y+175,w,120,22,C.muted);if(iline(s,cx,cy,x+d/2-cx,y+d/2-cy,'#41685A',2));circle(s,824,290,190,C.mint);text(s,'教学\n知识库',845,323,148,114,35,C.ink,true,'center');nodes.forEach(([x,y,d,t])=>{circle(s,x,y,d,'#244A3E');text(s,t,x+5,y+5,d-10,d-10,19,C.white,false,'center');});} // 01 { let s=base('', '教师培训', '开场5分钟。请老师回想最近一次“记得存过,却找不到”的资料。全课120分钟,产品操作25分钟,案例40分钟,练习与交流30分钟。',true); text(s,'让教学资料\n用起来',64,168,680,206,74,C.white,true); text(s,'知识库与腾讯 ima 教育应用',68,414,680,64,30,C.mint); text(s,'从一个单元开始,建立自己的教学资料库',68,518,670,78,25,'#C0D5CA');network(s); } //02 {let s=base('资料越来越多,使用依然费劲','从日常问题出发','请举手或口头互动:找不到资料、材料太多读不完、重复备课、成果难共享,哪一项最常见?不承诺具体节省时间。');cols(s,[['散落各处','电脑、微信与网盘\n各自留下一份资料'],['找不到重点','记得看过,却想不起\n文件名和关键段落'],['重复做整理','同一主题的材料\n每次重新阅读比较'],['经验难复用','优秀教案和课堂反思\n还停留在个人手里']]);callout(s,'今天从“保存资料”继续走到“围绕资料解决问题”');} //03 {let s=base('今天建立一个能回答问题的资料库','今天的成果','先展示目标成果:有资料、有问题、有依据、有教师修改。建议用随附演示材料,全程明确为模拟教学资料。');steps(s,[['几份资料','围绕同一主题\n小范围开始'],['一个问题','来自真实备课\n或日常工作'],['核对依据','返回原文\n检查上下文'],['一份成果','教师修改后\n保存并复用']]);callout(s,'你将带走一个小库、一份成果和一次查证记录');} //04 {let s=base('知识库,把资料组织成可用的资源','知识库基础','此处知识库是知识管理意义上的集合。带AI问答的知识库增加了内容检索、归纳和问答能力。用“某单元备课库”解释主题、资料、维护与复用。');text(s,'围绕一个主题\n持续积累与使用知识',64,230,650,160,48,C.ink,true);text(s,'资料、笔记、案例与经验\n经过组织,可以查找,也可以反复使用。',64,437,620,112,27,C.muted);let labels=['单元备课库','教研资料库','学校制度库'];labels.forEach((a,i)=>{shape(s,'roundRect',830,232+i*115,355,90,i===0?C.green:C.light);text(s,a,856,244+i*115,305,66,29,i===0?C.white:C.ink,true);});} //05 {let s=base('资料管理工具,各有适合的问题','知识库基础','这三类工具的能力可能重叠。表格比较常见使用方式,不声称文件夹、网盘或笔记没有搜索或AI功能。');table(s,['常见方式','你通常怎么用','主要帮助'],[['文件夹与网盘','目录、文件名、关键词','找到文件,保存和分发'],['笔记工具','记录、分类、关联','保留理解与思考'],['带 AI 问答的知识库','围绕内容提问、比较、归纳','用资料回答问题、形成初稿']],[245,420,487]);callout(s,'整理资料、标注来源和及时更新,依然重要');} //06 {let s=base('AI 如何使用你放进去的资料','知识库基础','这是常见检索增强问答的简化解释,并非ima内部技术架构说明。入库通常不是重新训练专属模型。检索可能遗漏,回答仍需要查证。');steps(s,[['解析资料','读取内容\n建立可检索的索引'],['查找片段','根据问题\n寻找相关材料'],['组织回答','结合找到的内容\n归纳与表达'],['回到原文','核对事实\n检查上下文']]);callout(s,'入库后仍需要核对答案与来源');} //07 {let s=base('知识库进入教师工作的五个环节','知识库基础','讲解价值时结合具体工作:定位课标相关段落、比较两份教案、起草课堂活动、记录实践反思、教研组共用。不要使用未经测量的效率数字。');const a=[['找','定位相关资料'],['读','比较与提取重点'],['用','形成教学初稿'],['留','补充实践反思'],['享','共用教研积累']];a.forEach(([big,t],i)=>{let x=64+i*235;circle(s,x+30,245,140,i%2?C.light:C.mint);text(s,big,x+30,245,140,140,58,C.green,true,'center');text(s,t,x,433,210,90,26,C.ink,true,'center');});} //08 {let s=base('第一个知识库,从一个具体主题开始','知识库基础','范围越大不代表越好用。举例:八年级物理光学备课、教研组同课异构、学校培训办理。学生使用应由学校与教师按实际要求安排。');table(s,['使用者','适合的主题','先放哪些材料'],[['教师个人','一个单元的备课','教学参考、已有教案、课后反思'],['教研组','一次同课异构教研','多份课例、听评课记录'],['学校管理','一项校务办理','现行制度、流程、常见问题'],['学生学习支持','教师筛选的学习专题','讲义、例题、学习提示']],[200,360,592],{h:350});callout(s,'起步建议:一个主题,3—5 份资料,一个真实问题');} //09 {let s=base('回答质量,取决于资料质量','知识库基础','请现场比较:清晰命名的文本PDF与缺页扫描件。识别不完整时先修复资料,不要仅靠追问。旧版、新版和矛盾资料需要清晰标注。');rows(s,[['来源可靠','保留出处、发布日期和适用范围'],['版本匹配','检查学科、年级、教材版本与资料时效'],['内容可读','确认没有缺页,扫描件能够正常识别'],['持续维护','处理重复、过期和相互冲突的内容']],64,213,1152,95);} //10 {let s=base('腾讯 ima,围绕知识库开展搜读写','认识腾讯 ima','来源:https://ima.tencent.com/download;https://ima.qq.com/。核对日期:2026-11-03。此课聚焦知识库基础能力,不讨论动态额度、价格和模型排名。产品功能与入口以授课账号实际版本为准。',true);text(s,'ima',64,211,480,180,135,C.mint,true);text(s,'资料收集、阅读理解\n与内容创作相连接',650,238,550,140,42,C.white,true);text(s,'本次聚焦\n资料入库 / 基于资料问答 / 笔记与共享',650,443,560,112,25,'#C0D5CA');callout(s,'用一个教学专题库,贯穿接下来的操作',596,true);} //11 {let s=base('一次备课,可以连起五种操作','认识腾讯 ima','能力来源:https://ima.tencent.com/download 与官方应用说明 https://apps.apple.com/cn/app/id6737188438。具体格式及端侧入口因版本而异,不在本页承诺。');rows(s,[['收资料、读资料','把相关文件、文章集中起来,辅助提取重点'],['问资料','针对指定资料范围,查询、比较和归纳'],['写内容','整理教学初稿,并加入教师的判断与修改'],['共用资料','围绕共同主题积累内容,管理成员与权限']],64,213,1152,95);} //12 {let s=base('先认识知识库入口与提问区域','ima 基础操作','截图来源:https://ima.qq.com/,2026-11-03,未登录Web首页。此截图仅说明可见入口。库内资料、来源、笔记及共享操作需要登录后演示,本次没有使用个人账号实测。');let b=await fs.readFile(path.join(BASE,'assets/ima-official-home.png'));s.images.add({blob:b.buffer.slice(b.byteOffset,b.byteOffset+b.byteLength),contentType:'image/png',alt:'腾讯ima未登录Web首页官方截图',position:{left:64,top:204,width:780,height:439},fit:'contain'});rows(s,[['知识库','添加与管理资料'],['提问区域','描述任务与要求'],['后续演示','登录后查看来源\n笔记与共享入口']],914,232,300,122);text(s,'官方 Web 首页截图,未登录状态',64,643,800,22,14,C.muted);} //13 {let s=base('建立“光与影”教学专题演示库','ima 基础操作','这里将原大纲“七年级科学”改为不绑定教材版本的“光与影教学专题演示库”。随附3份模拟材料,不能替代真实教材和课程标准。操作:新建库、加入3份Markdown资料、打开检查解析、记下资料名。授课前使用实际账号验证。');cols(s,[['主题说明','01_主题说明.md\n概念、适用范围\n与课堂目标'],['活动建议','02_活动建议.md\n控制变量\n与观察记录'],['课堂反思','03_课堂反思.md\n常见问题\n与改进线索']]);callout(s,'导入后逐份打开,确认内容可读、名称清晰');tag(s,'随附模拟材料',64,194,180);} //14 {let s=base('具体的问题,让回答更接近任务','ima 基础操作','演示先问“总结一下”,再用完整要求追问。不要伪造产品回答。本页是可复制的提问示例。');text(s,'起点',64,220,160,42,22,C.muted);text(s,'“帮我总结一下。”',64,271,1000,65,37,C.muted);text(s,'补充任务与要求',64,366,800,40,22,C.green,true);prompt(s,'请基于这 3 份资料,整理“光与影”专题的核心概念、\n活动建议和常见问题,用表格呈现,并标明资料名称。\n将资料依据与补充建议分开,缺少依据时明确说明。',64,423,1152,185);} //15 {let s=base('有引用,还需要回到原文核对','ima 基础操作','示例依据为随附模拟材料02,不是ima实测输出。展示答案中的一句话,然后打开原文,判断它是否受到支持。不要用“有来源”代替“来源支持”。');tag(s,'查证示例',64,219,150);text(s,'待核对的说法',64,291,500,42,23,C.muted);text(s,'“光源越远,影子一定越大。”',64,355,530,125,38,C.ink,true);shape(s,'roundRect',670,254,546,302,C.light);text(s,'原文依据',700,279,486,44,23,C.green,true);text(s,'保持光源与屏幕固定,\n改变物体在二者之间的位置。\n其他条件应保持不变。',700,351,476,150,28,C.ink);callout(s,'原文没有支持这个结论,需要纠正并说明条件');} //16 {let s=base('把回答继续加工成自己的教学积累','ima 基础操作','建议笔记包含来源、已核对结论、教师修改和课堂反馈。是否保存回库、具体入口请现场验证。强调教师的实践反馈会形成下一次更有价值的资料。');steps(s,[['核对','事实、条件\n与原文来源'],['修改','加入学情\n与教学判断'],['记录','标注出处\n与修改日期'],['更新','补充课堂反馈\n管理共享范围']]);callout(s,'一次回答可以结束,一份教学积累可以继续生长');} //17 {let s=base('四个场景,把知识库用到工作里','教育典型应用','案例共40分钟,建议单元备课15分钟、练习设计10分钟、教研积累8分钟、校务查询7分钟。案例成果为教学示例,不是实测的产品生成效果。',true);cols(s,[['备课','读懂材料\n组织教学活动'],['练习','明确考查点\n审核题目与答案'],['教研','比较不同课例\n积累实施经验'],['校务','查现行文件\n整理办事清单']],{dark:true});} //18 {let s=base('案例一:先从材料中提炼备课要点','备课案例','此表是根据随附模拟材料人工整理的示例成果,非课标原文、非ima实测输出。请现场提出问题后与此结构比较。重点检查目标、依据和活动之间的关系。');tag(s,'模拟成果示例',64,202,180);table(s,['备课要点','资料提供的信息','可追溯的依据'],[['核心概念','光沿直线传播,遮挡与影子的形成','01_主题说明'],['课堂观察','固定光源与屏幕,改变物体位置','02_活动建议'],['常见问题','同时改变多个条件,难以比较','03_课堂反思']],[240,570,342],{y:258,h:290});callout(s,'提问:这些资料分别提供了哪些目标、活动和问题线索?');} //19 {let s=base('案例一:形成可以修改的课堂活动初稿','备课案例','示例课堂40分钟安排:5分钟提出问题、15分钟控制变量观察、10分钟解释、10分钟交流。此为讲师设计建议,不是课标要求。教师需审核实验安全、学情与时间。');table(s,['目标','课堂活动建议','观察学生的表现'],[['解释影子的形成','用光源、物体和屏幕搭建装置','能否说明三者的关系'],['控制一个变化条件','固定光源与屏幕,移动物体','能否指出不变与变化条件'],['根据证据表达','比较观察记录并交流解释','能否用观察支持自己的说法']],[320,470,362],{h:295});callout(s,'补充给 AI:课时、学生已有经验、器材与限制条件');} //20 {let s=base('案例二:分层练习体现不同思维要求','练习设计案例','以下是基于光与影主题的示例题型,教师正式使用前检查科学性和课程匹配。基础题观察条件,应用题解释,拓展题实验设计。');cols(s,[['基础理解','指出形成影子需要的条件\n\n考查概念与关系'],['情境应用','解释同一装置中\n物体位置改变后的现象\n\n考查条件分析'],['探究设计','设计一个只改变\n物体位置的观察方案\n\n考查实验设计']]);callout(s,'要求同时给出考查点、参考答案、适用前提和设计意图');} //21 {let s=base('案例二:一道题,展示教师如何审核','练习设计案例','演示修正题干的条件。点光源模型,屏幕垂直光轴,物体在光源与屏幕之间,光源屏幕固定。物体靠近光源,屏幕上的影子通常变大。真实光源有大小时需注意半影,训练中使用理想化描述。');text(s,'初稿中的问题',64,224,520,44,24,C.muted);text(s,'“物体靠近光源,\n影子会怎样?”',64,298,520,150,40,C.ink,true);shape(s,'roundRect',655,219,561,350,C.light);text(s,'教师补充条件',687,249,490,44,26,C.green,true);text(s,'近似点光源与屏幕保持固定。\n物体位于光源和屏幕之间。\n只移动物体,使其靠近光源。',687,326,490,150,28,C.ink);text(s,'参考判断:屏幕上的影子变大。',687,510,490,44,24,C.green,true);callout(s,'审核四项:条件完整、答案正确、范围匹配、难度合适');} //22 {let s=base('案例三:比较课例,留下适用条件','教研积累案例','A和B为模拟课例,不是效果评估。教师共同讨论适用条件。不要根据两个课例声称一种教法必然更好。');table(s,['比较维度','课例 A:教师演示','课例 B:小组观察'],[['组织方式','教师操作,学生记录','学生分组操作与交流'],['优势与条件','器材少,过程容易统一','需要器材与操作常规'],['需要关注','每位学生是否真正观察到','是否控制变量,记录是否清晰'],['后续改进','增加预测与解释环节','增加角色分工和记录样例']],[230,461,461],{h:360});callout(s,'教研比较表应保留来源、课堂条件和待验证的问题');} //23 {let s=base('案例三:共享库需要持续维护','教研积累案例','共享功能与权限以授课账号当前版本为准。设置维护人、成员权限与更新规则。示例一个主题库中设置说明、资料、设计、反思四类内容,不承诺某种特定文件夹功能。');cols(s,[['放什么','主题说明与来源\n参考资料与教学设计\n实践反思与改进'],['谁维护','明确维护人与贡献者\n更新后标注日期\n保留适用范围'],['怎样共用','核对成员权限\n先审核再共享\n课堂反馈持续补充']]);callout(s,'共享的价值来自可理解、可追溯、可继续改进的内容');} //24 {let s=base('案例四:从制度文件整理办事清单','校务查询案例','使用材料04_校务办理模拟指南。全部制度、角色及流程为培训虚构示例,禁止作为学校正式规定。演示问题:校内培训申请需要哪些材料,经过哪些环节?');tag(s,'模拟制度示例',64,202,180);table(s,['办理环节','需要准备或确认','依据'],[['提交申请','主题、时间、参与对象与资源需求','模拟指南第1条'],['审核与沟通','交教研负责人确认,缺项补充','模拟指南第2条'],['活动后归档','活动记录与简要总结','模拟指南第3条']],[270,600,282],{y:256,h:285});callout(s,'实际使用时,列出正式文件名称、发布日期与对应条款');} //25 {let s=base('案例四:冲突与缺失,需要明确呈现','校务查询案例','这是文件使用习惯,不是法律意见。不能只凭日期自动断言某文件具有更高效力,要看适用范围、发布主体和学校确认。材料04未规定审批时限,回答应明确未找到。');cols(s,[['版本不同','并列文件日期\n核对适用范围\n向负责人确认'],['信息冲突','列出相互矛盾的条款\n说明差异\n暂停确定性结论'],['资料没有','明确“未找到依据”\n不补写审批时限\n列出待确认事项']]);callout(s,'一个可追溯的“待确认”,比编造一个具体答案更有用');} //26 {let s=base('现场练习:建立自己的教学专题库','现场练习','本环节12分钟独立操作、8分钟分享,最后10分钟使用习惯与答疑,合计30分钟。材料包包含3份光与影模拟资料、1份模拟校务文件和练习单。登录与导入需授课前验证。',true);text(s,'12',64,217,390,180,140,C.mint,true);text(s,'分钟动手操作',70,410,430,60,34,C.white,true);text(s,'再用 8 分钟交流与分享',70,493,460,70,25,'#C0D5CA');let a=['选择一个主题,导入 3—5 份资料','提出一个查询问题和一个综合问题','核对至少两处引用,进行一次修改','保存一份成果与查证记录'];a.forEach((t,i)=>{circle(s,650,235+i*88,36,C.mint);text(s,String(i+1),650,235+i*88,36,36,19,C.ink,true,'center');text(s,t,705,226+i*88,510,62,25,C.white);});} //27 {let s=base('一段可以反复使用的提问模板','现场练习','邀请老师把年级、学科、任务、资料范围、输出结构填完整。对于资料未涉及的内容不能保证模型一定拒答,必须检查实际回答。');prompt(s,'我正在为【年级/学科/主题】开展【具体任务】。\n请基于【指定资料范围】,完成【具体要求】。\n请用【表格/清单/教学设计初稿】呈现,并注明依据。\n将资料明确说明的内容与补充建议分开。\n没有找到依据的信息,请明确标注。',64,229,1152,328);callout(s,'不必一次问完,可以通过追问逐步补充条件');} //28 {let s=base('练习完成,能展示这五项成果','现场练习','邀请2至3位教师分享。重点观察查证与修改过程,不能只看生成文本是否流畅。');rows(s,[['资料可读','能打开原文,并说明主题与来源'],['问题明确','能够解释自己要解决的工作问题'],['依据可查','展示两处引用,以及核对后的判断'],['有过修改','至少一次追问或教师修改'],['成果可用','找到并打开保存的最终内容']],64,206,1152,81);} //29 {let s=base('让资料库保持有用的日常习惯','持续使用','不上传未获授权的敏感资料。按学校要求处理学生信息。共享前检查成员与内容权限。定期清理旧资料与失效内容,保留实践反思。');cols(s,[['范围小一点','围绕一个真实任务\n先积累高质量资料'],['维护勤一点','补充来源与日期\n检查旧版和重复内容'],['使用稳一点','核对正式使用的成果\n处理学生信息与共享权限']]);callout(s,'把自己的课堂反思补回库里,让下一次备课有据可循');} //30 {let s=base('', '交流与答疑','结尾预留答疑时间。作业:一周内带回一个专题库、一份教师修改后的成果、一次查证记录。培训重点是可持续的使用方法,不对教学效果作未经验证的承诺。',true);text(s,'从一个单元开始',64,160,1152,110,70,C.white,true);text(s,'让下一次备课,多一份可以复用的积累。',68,315,1140,70,34,C.mint);[['一个小库','聚焦一个真实主题'],['一份成果','经过教师检查与修改'],['一次查证','保留依据与核对记录']].forEach((a,i)=>{text(s,a[0],68+i*390,480,360,58,33,C.white,true);text(s,a[1],68+i*390,554,360,55,23,'#C0D5CA');});} await fs.mkdir(path.join(BASE,'build','previews'),{recursive:true}); await fs.mkdir(path.join(BASE,'outputs'),{recursive:true}); await fs.writeFile(path.join(BASE,'src','pptx-deck.json'),JSON.stringify(manifest,null,2)); const draft=path.join(BASE,'build','candidate.pptx'); await (await PresentationFile.exportPptx(p)).save(draft); console.log('Draft exported: '+draft); for(let i=0;i['--require-native-table-slide',String(n)])],explicitTotalSlideCount:30,requiredNativeTableOwnerSlides:[5,8,18,19,22,24],requiredNativeChartOwnerSlides:[],fontPolicy:{basis:'design',families:[FONT]},verifyArtifactToolImport:true,receiptPath:path.join(BASE,'build','validation.json')}); console.log('Finalized');