From 658b4f3f5d86e19093fb198ce584aabf38a3f9d1 Mon Sep 17 00:00:00 2001 From: KeyInfo Bot Date: Tue, 14 Jul 2026 00:01:29 +0800 Subject: [PATCH] Sync third-party and MCP marketplace plugins Constraint: Public skills are published only by explicit administrator action unless they are tracked third-party market sources. Confidence: high Scope-risk: narrow Directive: Keep private/internal skills out of the public marketplace and preserve normal incremental market Git history. Tested: Marketplace validation passed. --- .agents/plugins/marketplace.json | 24 +- config/external-sources.lock.json | 16 +- .../codex/.agents/plugins/marketplace.json | 24 +- .../plugins/mcp-playwright/MCP_SOURCE.json | 2 +- .../next-skills/THIRD_PARTY_SOURCE.json | 4 +- plugins/codex/plugins/ppt-master/README.md | 14 +- .../ppt-master/THIRD_PARTY_SOURCE.json | 4 +- .../ppt-master/skills/ppt-master/SKILL.md | 63 +- .../references/artifact-ownership.md | 8 +- .../ppt-master/references/executor-base.md | 26 +- .../ppt-master/references/semantic-svg.md | 8 +- .../ppt-master/references/shared-standards.md | 161 ++- .../ppt-master/references/strategist.md | 20 +- .../references/template-designer.md | 25 +- .../skills/ppt-master/scripts/README.md | 10 +- .../ppt-master/scripts/docs/svg-pipeline.md | 16 +- .../scripts/image_backends/backend_openai.py | 157 ++- .../skills/ppt-master/scripts/image_gen.py | 72 +- .../ppt-master/scripts/register_template.py | 312 ++++- .../scripts/svg_editor/annotations.py | 4 +- .../ppt-master/scripts/svg_editor/server.py | 20 + .../scripts/svg_editor/static/app.js | 4 +- .../ppt-master/scripts/svg_quality_checker.py | 1137 ++++++++++++++--- .../svg_to_pptx/drawingml/theme_fonts.py | 96 +- .../svg_to_pptx/pptx_package/builder.py | 799 +++++++++++- .../scripts/svg_to_pptx/pptx_package/cli.py | 72 +- .../pptx_package/template_structure.py | 456 +++++-- .../pptx_package/template_validation.py | 150 ++- .../scripts/template_preview_pptx.py | 92 +- .../ppt-master/templates/brands/README.md | 2 +- .../brands/anthropic/templates/design_spec.md | 33 +- .../templates/brands/brands_index.json | 8 +- .../brands/google/templates/design_spec.md | 12 +- .../templates/brands/中国电信/images/logo.png | Bin 0 -> 8325 bytes .../brands/中国电信/templates/design_spec.md | 72 ++ .../brands/中国电建/templates/design_spec.md | 21 +- .../brands/中汽研/templates/design_spec.md | 14 +- .../templates/decks/decks_index.json | 22 +- .../decks/中国电信/templates/01_cover.svg | 79 +- .../decks/中国电信/templates/02_chapter.svg | 84 +- .../decks/中国电信/templates/02_toc.svg | 159 ++- .../decks/中国电信/templates/03_content.svg | 76 +- .../decks/中国电信/templates/04_ending.svg | 70 +- .../decks/中国电信/templates/design_spec.md | 240 +--- .../decks/中国电建/images/中国水务logo.png | Bin 57784 -> 0 bytes .../decks/中国电建/images/华东院logo.png | Bin 131333 -> 0 bytes .../decks/中国电建/images/水电三局logo.png | Bin 20130 -> 0 bytes .../decks/中国电建/images/电建logo.png | Bin 83868 -> 0 bytes .../decks/中国电建/templates/01_cover.svg | 100 -- .../decks/中国电建/templates/02_chapter.svg | 81 -- .../decks/中国电建/templates/02_toc.svg | 112 -- .../decks/中国电建/templates/03_content.svg | 57 - .../decks/中国电建/templates/04_ending.svg | 92 -- .../decks/中国电建/templates/design_spec.md | 208 --- .../decks/中汽研/templates/01_cover.svg | 90 +- .../decks/中汽研/templates/02_chapter.svg | 82 +- .../decks/中汽研/templates/02_toc.svg | 183 ++- .../decks/中汽研/templates/03_content.svg | 101 +- .../decks/中汽研/templates/04_ending.svg | 124 +- .../decks/中汽研/templates/design_spec.md | 242 +--- .../decks/招商银行/images/cover_bg.png | Bin 122044 -> 0 bytes .../decks/招商银行/images/logo_crm_banner.png | Bin 22670 -> 0 bytes .../decks/招商银行/images/logo_dark.png | Bin 22493 -> 0 bytes .../decks/招商银行/images/logo_white.png | Bin 14066 -> 0 bytes .../decks/招商银行/images/page_header_bg.png | Bin 25166 -> 0 bytes .../decks/招商银行/images/ref_content_bg.png | Bin 56809 -> 0 bytes .../decks/招商银行/templates/01_cover.svg | 33 - .../decks/招商银行/templates/02_chapter.svg | 29 - .../decks/招商银行/templates/02_toc.svg | 46 - .../decks/招商银行/templates/03_content.svg | 71 - .../decks/招商银行/templates/04_ending.svg | 39 - .../decks/招商银行/templates/design_spec.md | 234 ---- .../decks/重庆大学/images/重庆大学logo.png | Bin 12302 -> 0 bytes .../decks/重庆大学/images/重庆大学logo2.png | Bin 27605 -> 0 bytes .../decks/重庆大学/templates/01_cover.svg | 74 -- .../decks/重庆大学/templates/02_chapter.svg | 52 - .../decks/重庆大学/templates/02_toc.svg | 80 -- .../decks/重庆大学/templates/03_content.svg | 56 - .../decks/重庆大学/templates/04_ending.svg | 62 - .../decks/重庆大学/templates/design_spec.md | 235 ---- .../templates/design_spec_reference.md | 4 +- .../academic_defense/templates/01_cover.svg | 49 - .../academic_defense/templates/02_chapter.svg | 36 - .../academic_defense/templates/02_toc.svg | 63 - .../academic_defense/templates/03_content.svg | 58 - .../academic_defense/templates/04_ending.svg | 52 - .../academic_defense/templates/design_spec.md | 216 ---- .../layouts/ai_ops/templates/01_cover.svg | 65 - .../layouts/ai_ops/templates/02_chapter.svg | 36 - .../layouts/ai_ops/templates/02_toc.svg | 51 - .../layouts/ai_ops/templates/03_content.svg | 37 - .../layouts/ai_ops/templates/04_ending.svg | 59 - .../layouts/ai_ops/templates/design_spec.md | 302 ----- .../ai_ops/templates/reference_style.svg | 154 --- .../government_blue/templates/01_cover.svg | 93 -- .../government_blue/templates/02_chapter.svg | 82 -- .../government_blue/templates/02_toc.svg | 107 -- .../government_blue/templates/03_content.svg | 78 -- .../government_blue/templates/04_ending.svg | 81 -- .../government_blue/templates/design_spec.md | 183 --- .../government_red/templates/01_cover.svg | 73 -- .../government_red/templates/02_chapter.svg | 66 - .../government_red/templates/02_toc.svg | 88 -- .../government_red/templates/03_content.svg | 66 - .../government_red/templates/04_ending.svg | 75 -- .../government_red/templates/design_spec.md | 176 --- .../templates/layouts/layouts_index.json | 104 +- .../medical_university/templates/01_cover.svg | 71 - .../templates/02_chapter.svg | 50 - .../medical_university/templates/02_toc.svg | 97 -- .../templates/03_content.svg | 78 -- .../templates/04_ending.svg | 79 -- .../templates/design_spec.md | 211 --- .../pixel_retro/templates/01_cover.svg | 138 -- .../pixel_retro/templates/02_chapter.svg | 130 -- .../layouts/pixel_retro/templates/02_toc.svg | 130 -- .../pixel_retro/templates/03_content.svg | 50 - .../pixel_retro/templates/04_ending.svg | 167 --- .../pixel_retro/templates/design_spec.md | 246 ---- .../templates/01_title_slide.svg | 21 + .../templates/02_title_content.svg | 23 + .../templates/03_section_header.svg | 23 + .../templates/04_two_content.svg | 29 + .../templates/05_comparison.svg | 43 + .../templates/06_title_only.svg | 15 + .../presentation_core/templates/07_blank.svg | 7 + .../templates/08_content_caption.svg | 29 + .../templates/09_picture_caption.svg | 29 + .../templates/10_hero_statement.svg | 23 + .../templates/11_editorial_split.svg | 29 + .../templates/12_three_card.svg | 37 + .../templates/13_kpi_dashboard.svg | 53 + .../templates/14_process_timeline.svg | 55 + .../templates/15_data_story.svg | 37 + .../templates/16_title_picture.svg | 24 + .../templates/17_two_picture_caption.svg | 49 + .../templates/18_screenshot_focus.svg | 49 + .../templates/19_chart_insight.svg | 60 + .../templates/20_table_summary.svg | 66 + .../templates/design_spec.md | 110 ++ .../templates/01_cover.svg | 78 -- .../templates/02_chapter.svg | 82 -- .../templates/02_toc.svg | 115 -- .../templates/03_content.svg | 41 - .../templates/04_ending.svg | 100 -- .../templates/design_spec.md | 312 ----- .../templates/spec_lock_reference.md | 55 +- .../ppt-master/workflows/create-brand.md | 38 +- .../ppt-master/workflows/create-template.md | 89 +- .../skills/ppt-master/workflows/index.md | 2 +- .../ppt-master/workflows/refine-spec.md | 2 +- .../workflows/restore-pptx-structure.md | 24 +- .../skills/ppt-master/workflows/routing.md | 2 +- .../plugins/shadcn/THIRD_PARTY_SOURCE.json | 4 +- plugins/codex/plugins/ui-ux-pro-max/README.md | 12 +- .../ui-ux-pro-max/THIRD_PARTY_SOURCE.json | 4 +- 156 files changed, 5013 insertions(+), 7830 deletions(-) create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/中国电信/images/logo.png create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/中国电信/templates/design_spec.md delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/images/中国水务logo.png delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/images/华东院logo.png delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/images/水电三局logo.png delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/images/电建logo.png delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/01_cover.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/02_chapter.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/02_toc.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/03_content.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/04_ending.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/design_spec.md delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/images/cover_bg.png delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/images/logo_crm_banner.png delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/images/logo_dark.png delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/images/logo_white.png delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/images/page_header_bg.png delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/images/ref_content_bg.png delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/01_cover.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/02_chapter.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/02_toc.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/03_content.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/04_ending.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/design_spec.md delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/images/重庆大学logo.png delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/images/重庆大学logo2.png delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/01_cover.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/02_chapter.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/02_toc.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/03_content.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/04_ending.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/design_spec.md delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/01_cover.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/02_chapter.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/02_toc.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/03_content.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/04_ending.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/design_spec.md delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/01_cover.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/02_chapter.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/02_toc.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/03_content.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/04_ending.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/design_spec.md delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/reference_style.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/01_cover.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/02_chapter.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/02_toc.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/03_content.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/04_ending.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/design_spec.md delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/01_cover.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/02_chapter.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/02_toc.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/03_content.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/04_ending.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/design_spec.md delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/01_cover.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/02_chapter.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/02_toc.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/03_content.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/04_ending.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/design_spec.md delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/01_cover.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/02_chapter.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/02_toc.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/03_content.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/04_ending.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/design_spec.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/01_title_slide.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/02_title_content.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/03_section_header.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/04_two_content.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/05_comparison.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/06_title_only.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/07_blank.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/08_content_caption.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/09_picture_caption.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/10_hero_statement.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/11_editorial_split.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/12_three_card.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/13_kpi_dashboard.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/14_process_timeline.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/15_data_story.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/16_title_picture.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/17_two_picture_caption.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/18_screenshot_focus.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/19_chart_insight.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/20_table_summary.svg create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/design_spec.md delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/01_cover.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/02_chapter.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/02_toc.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/03_content.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/04_ending.svg delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/design_spec.md diff --git a/.agents/plugins/marketplace.json b/.agents/plugins/marketplace.json index d711d432..86dd6dbe 100644 --- a/.agents/plugins/marketplace.json +++ b/.agents/plugins/marketplace.json @@ -280,6 +280,18 @@ }, "category": "设计" }, + { + "name": "oh-my-codex", + "source": { + "source": "local", + "path": "./plugins/codex/plugins/oh-my-codex" + }, + "policy": { + "installation": "AVAILABLE", + "authentication": "ON_INSTALL" + }, + "category": "开发工具" + }, { "name": "ui-ux-pro-max", "source": { @@ -304,18 +316,6 @@ }, "category": "开发工具" }, - { - "name": "oh-my-codex", - "source": { - "source": "local", - "path": "./plugins/codex/plugins/oh-my-codex" - }, - "policy": { - "installation": "AVAILABLE", - "authentication": "ON_INSTALL" - }, - "category": "开发工具" - }, { "name": "ppt-master", "source": { diff --git a/config/external-sources.lock.json b/config/external-sources.lock.json index d65db062..d2fa1ac8 100644 --- a/config/external-sources.lock.json +++ b/config/external-sources.lock.json @@ -24,8 +24,8 @@ "repo": "https://github.com/nextlevelbuilder/ui-ux-pro-max-skill.git", "ref": "main", "adapter": "claude-skill", - "commit": "3da52ff1cab1be91848072ec1be5f493d730fd5f", - "syncedAt": "2026-07-10T16:00:00Z" + "commit": "0468898265b1552e19f96e9da448e971b6d325fd", + "syncedAt": "2026-07-13T16:00:00Z" }, { "id": "caveman", @@ -51,8 +51,8 @@ "repo": "https://github.com/shadcn-ui/ui.git", "ref": "main", "adapter": "claude-skill", - "commit": "3cdaa6eb2f0da27aca8598cb752c32d840e06940", - "syncedAt": "2026-07-10T16:00:00Z" + "commit": "bb8ba0daceb717eefc3a6ecb3457f28ca770d138", + "syncedAt": "2026-07-13T16:00:00Z" }, { "id": "frontend-slides", @@ -87,8 +87,8 @@ "repo": "https://github.com/hugohe3/ppt-master.git", "ref": "main", "adapter": "claude-skill", - "commit": "8f76b6fcef5f24c8716894adeb6fe24c5a418bc3", - "syncedAt": "2026-07-12T16:00:00Z" + "commit": "465e3b4149b852d33ddd1cb94ac059401fe4e823", + "syncedAt": "2026-07-13T16:00:00Z" }, { "id": "next-skills", @@ -96,8 +96,8 @@ "repo": "https://github.com/vercel/next.js.git", "ref": "canary", "adapter": "skill-collection", - "commit": "31541356c21bc389150b958379acb26aa7e97b22", - "syncedAt": "2026-07-12T16:00:00Z" + "commit": "41b823880d688b3e9f9aae3323b08ddd457240c2", + "syncedAt": "2026-07-13T16:00:00Z" } ] } diff --git a/plugins/codex/.agents/plugins/marketplace.json b/plugins/codex/.agents/plugins/marketplace.json index fb9c6731..9654e912 100644 --- a/plugins/codex/.agents/plugins/marketplace.json +++ b/plugins/codex/.agents/plugins/marketplace.json @@ -280,6 +280,18 @@ }, "category": "设计" }, + { + "name": "oh-my-codex", + "source": { + "source": "local", + "path": "./plugins/oh-my-codex" + }, + "policy": { + "installation": "AVAILABLE", + "authentication": "ON_INSTALL" + }, + "category": "开发工具" + }, { "name": "ui-ux-pro-max", "source": { @@ -304,18 +316,6 @@ }, "category": "开发工具" }, - { - "name": "oh-my-codex", - "source": { - "source": "local", - "path": "./plugins/oh-my-codex" - }, - "policy": { - "installation": "AVAILABLE", - "authentication": "ON_INSTALL" - }, - "category": "开发工具" - }, { "name": "ppt-master", "source": { diff --git a/plugins/codex/plugins/mcp-playwright/MCP_SOURCE.json b/plugins/codex/plugins/mcp-playwright/MCP_SOURCE.json index 43b56ef3..c92f2d69 100644 --- a/plugins/codex/plugins/mcp-playwright/MCP_SOURCE.json +++ b/plugins/codex/plugins/mcp-playwright/MCP_SOURCE.json @@ -3,5 +3,5 @@ "name": "playwright浏览器自动化操作", "version": "20260605", "keySource": "none", - "syncedAt": "2026-07-12T16:01:37Z" + "syncedAt": "2026-07-13T16:01:28Z" } diff --git a/plugins/codex/plugins/next-skills/THIRD_PARTY_SOURCE.json b/plugins/codex/plugins/next-skills/THIRD_PARTY_SOURCE.json index 809d4338..a193cbc0 100644 --- a/plugins/codex/plugins/next-skills/THIRD_PARTY_SOURCE.json +++ b/plugins/codex/plugins/next-skills/THIRD_PARTY_SOURCE.json @@ -2,8 +2,8 @@ "sourceId": "next-skills", "repo": "https://github.com/vercel/next.js.git", "ref": "canary", - "commit": "31541356c21bc389150b958379acb26aa7e97b22", + "commit": "41b823880d688b3e9f9aae3323b08ddd457240c2", "adapter": "skill-collection", "sourcePath": "skills", - "syncedAt": "2026-07-12T16:00:00Z" + "syncedAt": "2026-07-13T16:00:00Z" } diff --git a/plugins/codex/plugins/ppt-master/README.md b/plugins/codex/plugins/ppt-master/README.md index 86f765c2..c58952f9 100644 --- a/plugins/codex/plugins/ppt-master/README.md +++ b/plugins/codex/plugins/ppt-master/README.md @@ -13,7 +13,17 @@ English | [中文](./README_CN.md)
-This project is kept free and open source with the support of PackyCode, APIKEY.FUN, RunAPI, YouYun ZhiSuan and other sponsors. +This project is kept free and open source with the support of Kimi, PackyCode, APIKEY.FUN, RunAPI, YouYun ZhiSuan and other sponsors. + +

+ Kimi +

+ +Thanks to [Kimi](https://www.kimi.com/code/?aff=ppt-master) for sponsoring this project! [Kimi K2.7](https://platform.kimi.ai/docs/guide/kimi-k2-7-code-quickstart) is an open-source agentic model developed by Moonshot AI. With PPT Master, Kimi can understand source materials such as PDFs, DOCX files, and web pages, identify key points, structure the narrative, and generate a natively editable PPTX that you can continue refining in PowerPoint. + +**Try [Kimi Code](https://www.kimi.com/code/?aff=ppt-master), or access the API through the Kimi Open Platform ([中文站](https://platform.kimi.com?aff=ppt-master) | [Global](https://platform.kimi.ai?aff=ppt-master)).** + +
@@ -397,6 +407,8 @@ PPT Master is currently built and maintained primarily by me. Every new template **Corporate sponsors** +KimiPackyCode   APIKEY.FUN diff --git a/plugins/codex/plugins/ppt-master/THIRD_PARTY_SOURCE.json b/plugins/codex/plugins/ppt-master/THIRD_PARTY_SOURCE.json index c3147ba5..fa95b323 100644 --- a/plugins/codex/plugins/ppt-master/THIRD_PARTY_SOURCE.json +++ b/plugins/codex/plugins/ppt-master/THIRD_PARTY_SOURCE.json @@ -2,8 +2,8 @@ "sourceId": "ppt-master", "repo": "https://github.com/hugohe3/ppt-master.git", "ref": "main", - "commit": "8f76b6fcef5f24c8716894adeb6fe24c5a418bc3", + "commit": "465e3b4149b852d33ddd1cb94ac059401fe4e823", "adapter": "claude-skill", "sourcePath": "skills/ppt-master", - "syncedAt": "2026-07-12T16:00:00Z" + "syncedAt": "2026-07-13T16:00:00Z" } diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/SKILL.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/SKILL.md index d7fc024a..607c5a4e 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/SKILL.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/SKILL.md @@ -34,7 +34,7 @@ description: "多格式源文档到高质量 SVG 页面再导出 PPTX 的多阶 > 5. **NO SPECULATIVE EXECUTION** — "Pre-preparing" content for subsequent Steps is FORBIDDEN (e.g., writing SVG code during the Strategist phase) > 6. **NO SUB-AGENT SVG GENERATION** — Executor Step 6 SVG generation is context-dependent and MUST be completed by the current main agent end-to-end. Delegating page SVG generation to sub-agents is FORBIDDEN > 7. **SEQUENTIAL PAGE GENERATION ONLY** — In Executor Step 6, after the global design context is confirmed, SVG pages MUST be generated sequentially page by page in one continuous pass. Grouped page batches (for example, 5 pages at a time) are FORBIDDEN -> 8. **SPEC_LOCK RE-READ PER PAGE** — Before generating each SVG page, Executor MUST `read_file /spec_lock.md`. All colors / fonts / icons / images MUST come from this file — no values from memory or invented on the fly. Executor MUST also look up the complete `pptx_masters` / `pptx_layouts` structure, `pptx_structure.template_adherence` when present, the current page's `page_rhythm` (`anchor` / `dense` / `breathing`), `page_layouts` (the input template SVG), and `page_charts`. Master/Layout structure exists before drawing; export never infers it later. This rule exists to resist context-compression drift on long decks and to break the uniform "every page is a card grid" default +> 8. **SPEC_LOCK RE-READ PER PAGE** — Before generating each SVG page, Executor MUST `read_file /spec_lock.md`. All colors / fonts / icons / images MUST come from this file — no values from memory or invented on the fly. Executor MUST also read `pptx_structure.mode`, the current page's `page_rhythm` (`anchor` / `dense` / `breathing`), and `page_charts`. Only a deck/layout template route (`mode: structured`) looks up `page_layouts` (the input template SVG), `page_pptx_layouts` (the page assignment), `pptx_masters`, `pptx_layouts` (the unique reusable roster), and `template_adherence`; free-design and brand-only routes use `mode: flat` and omit those sections. This rule exists to resist context-compression drift on long decks and to break the uniform "every page is a card grid" default > 9. **SVG MUST BE HAND-WRITTEN, NOT SCRIPT-GENERATED** — Every SVG page is written by the main agent directly, one page at a time (see rules 6 and 7). Writing or running a Python / Node / shell script that produces the SVG files in batch — looping over pages, templating from data, or emitting them via a generator — is FORBIDDEN, including under "save tokens", "quick draft", or "user is in a hurry" pretexts. The script-generation path was tried on a feature branch and abandoned: cross-page visual consistency depends on per-page authoring with full upstream context, which a generator script cannot reproduce. **Narrow exception**: `preset_shape_svg.py` may print one deterministic stock-shape fragment to stdout after the main agent has selected its semantic role, frame, and paint. It cannot write `svg_output/`, choose layout, batch shapes, or generate a page; the main agent reads the fragment and inserts it through the normal hand-authored page edit > 10. **FOLLOW DETERMINISTIC ROUTING RULES** — Do not add blocking routing questions when this skill defines a route. If the user request violates a route precondition, state the required prerequisite and stop that route instead of asking the user to choose around the rule. Ordinary finite options, stylistic preferences, and recoverable details are surfaced with a recommended value plus alternatives at the next existing confirmation gate. @@ -141,11 +141,12 @@ keep model context small. Mechanical normalization may express the source facts in the current explicit SVG contract and expand fixed-layer group wrappers into direct atoms, but it MUST NOT merge, split, promote, demote, rename, or re-parent source structure. Export compiles the selected contract and never -infers a different one. Because the current structured roster materializes only -identities referenced by emitted page prototypes, `mirror` is available only -when every source Layout is used by a source Slide and every source Master is -reachable through those Layouts. Otherwise stop and report the exact -unreachable identities; never drop them or invent a carrier page. +infers a different one. Mirror emits one complete page prototype per source +Slide plus one definition-only `layout_.svg` prototype for every +source Layout unused by those Slides. The independent Master/Layout roster then +registers the complete supported source graph without publishing synthetic +carrier pages. Stop only when required native evidence is missing or unsupported; +never silently drop or merge an identity. **FALLBACK**: Ambiguous requests such as "make this PPT more professional" require exactly one discriminator question: preserve original page count/order and slide wording, or treat the deck as source material and restructure it? @@ -244,7 +245,7 @@ Do **not** reinterpret this boundary as 1:1 redesign or free SVG generation. Use |---|---| | One or more explicit template workspace paths (each resolves to `templates/design_spec.md`, or to a compatible legacy-flat root `design_spec.md`, with `kind: brand` / `kind: layout` / `kind: deck` in YAML frontmatter) | Normalize each source directory, read its `kind`, dispatch per the kind matrix below, fuse if multiple | | Current `create-template` workflow just completed project scope and validated its exact `/` workspace | Consume that single workspace in place; it cannot join multi-path fusion | -| Anything else — bare template names ("用 academic_defense"), style descriptions ("麦肯锡风格"), brand mentions ("招商银行风格"), vague intent ("想用个模板"), or silence | Skip Step 3, free design | +| Anything else — bare template names ("用 presentation_core"), style descriptions ("麦肯锡风格"), brand mentions ("中国电信风格"), vague intent ("想用个模板"), or silence | Skip Step 3, free design | There is no slug matching, no name lookup, no fuzzy resolution. A name without a path does not trigger — the user must give a path the AI can `cd` into. @@ -252,7 +253,7 @@ There is no slug matching, no name lookup, no fuzzy resolution. A name without a > Style descriptions ("麦肯锡风格" / "Keynote 风" / "极简风" / etc.) never trigger Step 3. They flow into the Strategist confirmation stage as a style brief (color / typography / tone in fields e–g). -> Bare names ("academic_defense", "招商银行", "anthropic") do NOT trigger Step 3 even if a matching directory exists in the library. The user must give a path. AI must not "helpfully" resolve a name to a path. +> Bare names ("presentation_core", "中国电信", "anthropic") do NOT trigger Step 3 even if a matching directory exists in the library. The user must give a path. AI must not "helpfully" resolve a name to a path. > "What templates exist?" is out-of-band Q&A — answer by listing entries from `brands_index.json` / `layouts_index.json` / `decks_index.json` together with their paths. Listing alone does not advance the pipeline; the user must send a path back to trigger Step 3. @@ -303,7 +304,7 @@ A project-scoped workspace has the same portable routing as a library workspace. Legacy template packages may ship `native_structure.json` + `source_template.pptx`, omit root Master identity, use direct atomic placeholders, or carry old baseline/distillation metadata. Do not copy or consume those semantic contracts through Step 3. Run [`restore-pptx-structure`](workflows/restore-pptx-structure.md) on the package first, then return with the migrated workspace path. Old flat packaging remains readable when its SVG structure is already current. -The Strategist confirmation stage decides whether the selected template is used `strict` or `adaptive`. New projects use `pptx_structure.mode: structured`, map every page to one input SVG in `page_layouts`, and write complete `pptx_masters` / `pptx_layouts` output mappings before SVG generation. Strict preserves the template's declared Master/Layout/slot contract. Adaptive keeps the template Master and may assign a new Layout key during authoring when the composition genuinely changes. Non-mirror paint and typography follow the project skin rules. +The Strategist confirmation stage decides whether the selected deck/layout template is used `strict` or `adaptive`. Those template projects use `pptx_structure.mode: structured`, map every page to one input SVG in `page_layouts`, declare unique reusable identities in `pptx_masters` / `pptx_layouts`, and assign each page through `page_pptx_layouts` before SVG generation. A Layout definition may remain unused by generated pages when it names an installed template SVG as its prototype source. Brand-only projects remain on the free-design `mode: flat` route. Strict preserves the template's declared Master/Layout/slot contract. Adaptive keeps the template Master and may define and assign a new Layout key during authoring when the composition genuinely changes. Non-mirror paint and typography follow the project skin rules. #### Multi-path fusion @@ -350,9 +351,9 @@ When fusion happens (any multi-path case), the resulting `/templates/de ```markdown > **Fused from:** -> - deck: `templates/decks/招商银行/` (base) +> - deck: `templates/decks/中国电信/` (base) > - brand: `templates/brands/anthropic/` (identity override) -> - layout: `templates/layouts/academic_defense/` (structure override) +> - layout: `templates/layouts/presentation_core/` (structure override) > - conflicts resolved: Color Scheme from anthropic(user picked a) ``` @@ -621,7 +622,7 @@ python3 ${SKILL_DIR}/scripts/svg_editor/server.py --live --daemon > Image facts: trust the `analysis/image_analysis.csv` regenerated at the end of Step 5. If `images/` changed since (the user swapped or added files), re-run `python3 ${SKILL_DIR}/scripts/analyze_images.py /images` before laying images out — facts are re-derived on use, never a stale store (Step 4 image-facts note). -**Per-page spec_lock re-read (Mandatory)**: before **each** SVG page, `read_file /spec_lock.md` and use only its colors / fonts / icons / images, plus the complete `pptx_masters` / `pptx_layouts` structure and the per-page `page_rhythm` / `page_layouts` / `page_charts` lookups. Resists context-compression drift on long decks. See executor-base.md §2.1. +**Per-page spec_lock re-read (Mandatory)**: before **each** SVG page, `read_file /spec_lock.md` and use only its colors / fonts / icons / images, plus `pptx_structure.mode` and the per-page `page_rhythm` / `page_charts` lookups. Read `page_layouts` / `page_pptx_layouts` / `pptx_masters` / `pptx_layouts` only on a structured deck/layout template route; they are absent in flat free-design and brand-only projects. Resists context-compression drift on long decks. See executor-base.md §2.1. > ⚠️ **Main-agent only**: SVG generation MUST stay in the current main agent — page design depends on full upstream context. Do NOT delegate to sub-agents. > ⚠️ **Generation rhythm**: generate pages sequentially, one at a time, in the same continuous context. Do NOT batch (e.g., 5 per group). @@ -632,7 +633,7 @@ Each completed SVG MUST be a standalone, complete representation of that slide's Template pages MUST start from the complete `page_layouts` SVG, keep all inherited visible objects in `svg_output/`, and preserve the locked root Master/Layout identity plus stable atomic Master/Layout and slot ids. Strict keeps the prototype structure unchanged. Adaptive keeps its Master contract and, when Layout atoms or slot topology/bounds genuinely evolve, assigns a new key/name and updates `spec_lock.md` immediately. Non-mirror fill/stroke/effects/font sizes still follow `spec_lock`. -Free-design and brand-only pages are also structured from the first draft. Use the planned Master roster and page Layout mapping, author Master/Layout fixed visuals only as direct root atoms (never ``), and author reusable content zones as top-level slot groups with positive bounds plus exactly one compatible carrier. Every mapped page MUST mark the standard slots it actually has — `title` / `subtitle` / `body` / `picture` / `slide-number` / `footer` — and its `data-pptx-layer` marks: the deck-wide background and every-page chrome as `master`, this layout key's static framing (including chrome repeated on content pages but absent from the cover) as `layout`, per [`executor-base.md`](references/executor-base.md) §1.2. Repeated chrome stays on its appropriate Master/Layout layer; a per-page heading that should not remain Slide-local is authored as a `title` or `subtitle` slot, never as a fixed Layout atom. Any text or image whose value varies across pages sharing one Layout key MUST be carried by a slot or remain Slide-local. A page shipping only a marked background exports a bare Master and an empty Layout. A Layout may intentionally have zero slots — a stated decision for a fixed composition, never a silent default. Do not add `data-pptx-layout-kind`, `distilled`, `utility`, or a full-page fake slot. +Free-design and brand-only pages use `pptx_structure.mode: flat`. Draw the complete page directly: keep backgrounds, repeated chrome, headings, text, images, and decoration as ordinary Slide-local SVG content. Do not plan `pptx_masters` / `pptx_layouts` / `page_pptx_layouts`, do not add root Master/Layout identity, and do not add `data-pptx-layer` or `data-pptx-placeholder` metadata. Group logical content normally with top-level `` elements. Export materializes one clean project-owned Master plus one Blank Layout, applies the locked theme colors/fonts/title-body defaults, removes stock content placeholders and unused built-in Layouts, and retains only the standard date/footer/slide-number capability hooks. It does not promote or deduplicate page content. Do not duplicate specialized identity with `data-pptx-role`. Add it only to structural page-frame objects whose package, page-number, or animation behavior is not already expressed by `data-pptx-layer`, `data-pptx-placeholder`, or `data-pptx-native`; such an element needs a stable unique `id`. Do not add generic content roles to ordinary titles, body text, cards, KPIs, diagrams, charts, icons, or images. Full contract: [`references/semantic-svg.md`](references/semantic-svg.md). @@ -648,7 +649,7 @@ python3 ${SKILL_DIR}/scripts/svg_quality_checker.py ``` - Any `error` (banned SVG features, viewBox mismatch, spec_lock drift, etc.) MUST be fixed before proceeding — return to Visual Construction, regenerate that page, re-run check. - `warning` entries (low-res image, non-PPT-safe font tail, etc.): fix when straightforward, otherwise acknowledge and release. -- **PPTX-structure warnings are the exception — never acknowledge-and-release.** For each empty-Layout / framing-only-Layout / bare-Master / duplicate-layout-key warning, output one disposition line: either the fix applied (merge keys in `spec_lock.md pptx_layouts` + SVG roots, mark the missing slots/layers) or why the flagged state is intended (e.g. "P01 cover is a fixed composition, zero-slot by design"). "0 errors" alone does not pass this gate. +- **Structured template routes only — PPTX-structure warnings are the exception.** For each empty-Layout / framing-only-Layout / bare-Master / duplicate-layout-key warning, output one disposition line: either the fix applied (merge keys in `spec_lock.md pptx_layouts` + SVG roots, mark the missing slots/layers) or why the flagged state is intended (e.g. "P01 cover is a fixed composition, zero-slot by design"). Flat free-design and brand-only routes have no positive Master/Layout checkpoint; the checker instead enforces a complete flat lock including colors/fonts/title-body defaults, plus the absence of Master/Layout/layer/placeholder metadata. "0 errors" alone does not pass a structured template gate when such warnings remain undispositioned. - Run against `svg_output/` (not after `finalize_svg.py` — finalize rewrites SVG and masks violations). **Logic Construction Phase**: generate speaker notes → `/notes/total.md` @@ -660,7 +661,7 @@ python3 ${SKILL_DIR}/scripts/svg_quality_checker.py - [x] First-page gate run after page 1 (errors fixed before page 2) - [x] All SVGs generated to svg_output/ - [x] svg_quality_checker.py passed (0 errors) -- [x] PPTX-structure warnings dispositioned one by one (each fixed or stated as intended) +- [x] Structured-template PPTX warnings dispositioned one by one when applicable - [x] Speaker notes generated at notes/total.md ``` @@ -738,10 +739,21 @@ python3 ${SKILL_DIR}/scripts/svg_to_pptx.py > pages remain ordinary SVG pictures unless the user independently accepts the > results of an unsupported Office conversion. -> **PPTX structure mode** — release export requires -> `spec_lock.md` `pptx_structure.mode: structured`, a complete -> `pptx_masters` roster, and exactly one `pptx_layouts` row per page in -> ` | | ` form. Every SVG +> **PPTX structure mode** — release export reads the explicit route from +> `spec_lock.md`. Free-design and brand-only projects use +> `pptx_structure.mode: flat`, omit `pptx_masters` / `pptx_layouts` / +> `page_pptx_layouts` / `page_layouts`, and author no Master/Layout/layer/placeholder metadata in +> SVG. Export keeps every represented object Slide-local while materializing +> one clean project-owned Master and one Blank Layout from the current lock; +> stock content placeholders and unused built-in Layouts are removed; only the +> standard date/footer/slide-number capability hooks remain. +> +> Deck/layout template projects use `pptx_structure.mode: structured`, a +> complete `pptx_masters` roster, one unique `pptx_layouts` definition per +> reusable Layout, and exactly one `page_pptx_layouts` assignment per page. +> A Layout definition records Master key, PowerPoint picker name, and either a +> `P` or `template:` prototype source; an unused Layout uses a template prototype +> and is registered without a published carrier slide. Every SVG > root repeats the Master/Layout keys and picker names. Master/Layout fixed > visuals are direct root atoms; a `` is > forbidden. Reusable slots are direct root `` elements with positive @@ -749,23 +761,26 @@ python3 ${SKILL_DIR}/scripts/svg_to_pptx.py > uses only the explicit `object` + `proxy` fallback, and a Layout may > intentionally have zero slots. > -> Export creates the declared Masters and Layouts, promotes the represented +> Structured template export creates the declared Masters and Layouts, +> promotes the represented > atoms, binds slot carriers, installs the locked theme/text defaults, and > reopens the candidate package to verify Presentation → Master → Layout → > Slide registration, picker names, static-object rosters, placeholder > type/index/bounds, carrier bindings, hidden proxies, and zero-slot Layouts. > It never selects pages, clusters visuals, promotes repeated chrome by -> heuristic, or invents missing structure. Legacy `baseline`, `template`, +> heuristic, or invents missing structure. Legacy structured/template projects +> using `baseline`, `template`, > `preserve`, `layout_strategy`, `data-pptx-layout-kind`, -> `distilled`/`utility`, direct atomic placeholders, or missing Master +> `distilled`/`utility`, direct atomic placeholders, or incomplete Master > identity must run > [`restore-pptx-structure`](workflows/restore-pptx-structure.md) before > export. > **Template structured export** — `page_layouts` records the complete -> input prototype per page while `pptx_masters` / `pptx_layouts` record the -> output structure from planning onward. Strict keeps the prototype +> input prototype per page, `pptx_masters` / `pptx_layouts` record the unique +> reusable output roster, and `page_pptx_layouts` records page assignment. +> Strict keeps the prototype > Master/Layout/slot contract. Adaptive keeps its Master and may assign a new > Layout identity during page authoring only when fixed Layout atoms or slot > topology/bounds change; the lock is updated immediately. Non-mirror skin diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/artifact-ownership.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/artifact-ownership.md index 9d08f526..c9f9789f 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/artifact-ownership.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/artifact-ownership.md @@ -18,7 +18,7 @@ Global artifact ownership rules for PPT Master projects. | `analysis/.slide_library.json` | Native PPTX structure facts | Text slots, geometry, native tables, native chart caches, SmartArt nodes/connections | Direct PPTX workflows use as native fill/structure contract | | `analysis/image_analysis.csv` | Regenerated image fact view | Measured facts about the current `images/` folder | Re-run `analyze_images.py` before reading image facts after changes | | `design_spec.md` | Human design narrative | Explains design intent, outline, rationale, and resource plan | Strategist writes; humans and later roles read for intent | -| `spec_lock.md` | Execution contract | Literal colors, typography, icons, images, page rhythm, input template prototypes, charts, Master roster, and complete page-to-Master/Layout mapping | Strategist writes the initial structured contract; Executor re-reads it before every page and may add a new adaptive Layout identity only while authoring the page that first needs it; `restore-pptx-structure` owns legacy migration | +| `spec_lock.md` | Execution contract | Literal colors, typography, icons, images, page rhythm, charts, and the route's PowerPoint structure mode; deck/layout template routes additionally own input prototypes, the Master roster, and the complete page-to-Master/Layout mapping | Strategist writes the route-specific contract; Executor re-reads it before every page and may add a new adaptive Layout identity only on a structured template route while authoring the page that first needs it; `restore-pptx-structure` owns legacy template migration | | `images/` | Runtime image pool | User, extracted, AI, web, formula, slice, EMF/WMF assets | Step 5 writes here; `analysis/image_analysis.csv` derives from current contents | | `icons/` | Project icon inventory | Icons copied by `icon_sync.py` for this project | Executor uses locked project icons; exporter may fall back to global library only as documented | | `templates/` | Project template reference | Step 3 imported specs, template SVGs, and non-image assets | Strategist/Executor read only when Step 3 is triggered | @@ -42,9 +42,9 @@ Global artifact ownership rules for PPT Master projects. | Sources read policy | In `sources/`, read content-type files (`.md` / `.markdown` / `.txt` / `.csv` / `.tsv` / `.json` / `.jsonl` / `.yaml` / `.yml`) and judge by content — a `.json` / `.csv` may be core content or just data. Exclude known sidecars: `*.conversion_profile.json` and `*_files/image_manifest.json`. `analysis/` facts (`source_profile.json`, `.slide_library.json`) are read per Step 4 / direct-PPTX workflow, not in the `sources/` content scan. | | PPTX structure | `slide_library.json` owns native geometry, slot facts, and SmartArt layout/relationships for direct PPTX workflows. | | Design contract | `design_spec.md` explains; `spec_lock.md` executes. Executor must not infer execution values from prose. | -| Free-design structure authority | Strategist plans the Master roster and complete page-to-Master/Layout mapping before SVG generation. `spec_lock.md` owns that mapping; `svg_output/` owns the matching root identities, atomic Master/Layout visuals, slot groups, bounds, and carriers. Export never infers structure. | -| Template structure authority | `page_layouts` owns the per-page input prototype. `pptx_masters` and `pptx_layouts` own the complete output structure from planning onward; strict keeps the prototype contract, while adaptive may create a new Layout identity during page authoring and updates the lock immediately. Templates validate provenance but never add missing visible objects during export. | -| Legacy structure migration | [`restore-pptx-structure`](../workflows/restore-pptx-structure.md) owns conversion of old unmapped/distilled/preserve SVG projects and legacy template packages into the current structured contract. The exporter does not migrate or visually cluster them. | +| Free-design / brand-only packaging authority | `spec_lock.md` declares `pptx_structure.mode: flat` and omits `pptx_masters`, `pptx_layouts`, `page_pptx_layouts`, and `page_layouts`. `svg_output/` owns the complete Slide-local visual design without root Master/Layout identity, fixed-layer ownership, or placeholder metadata. Export materializes one clean project-owned Master plus one Blank Layout, applies the locked theme defaults, removes stock content placeholders/Layout inventory, and retains only the standard date/footer/slide-number capability hooks. | +| Template structure authority | `page_layouts` owns each page's authoring-input prototype. `pptx_masters` / `pptx_layouts` own the unique reusable output definitions, while `page_pptx_layouts` owns page assignment. Strict keeps the prototype contract; adaptive may create a new Layout definition during page authoring and updates its assignment immediately. Unused definitions may register without a published Slide. Templates validate provenance but never add missing visible page objects during export. | +| Legacy structure migration | [`restore-pptx-structure`](../workflows/restore-pptx-structure.md) owns conversion of old unmapped/distilled/preserve structured projects and legacy template packages into the current template contract. An intentional free-design or brand-only `flat` project is not a migration input. The exporter does not migrate or visually cluster legacy template structure. | | Image facts | `images/` is live state; `analysis/image_analysis.csv` is a regenerated view, not a durable cache. | | SVG source | `svg_output/` is the only author source for generated pages. | | Page-design closure | On SVG-authoring routes, every visible exported-slide object exists in the corresponding page SVG or an explicitly referenced visual asset. | diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-base.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-base.md index 2baa15a1..2d72cafd 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-base.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-base.md @@ -4,7 +4,7 @@ **Hard rule — complete page SVG**: Every visible object intended for the exported slide MUST exist in the final page SVG or be explicitly referenced by it. Templates and `spec_lock.md` guide construction; they are not export-time overlays for missing visible content. -**Hard rule — structure from the first page draft**: Every new page reads its locked Master/Layout row and declares `data-pptx-master`, `data-pptx-master-name`, `data-pptx-layout`, and `data-pptx-layout-name` on the root. Do not add `data-pptx-layout-kind` or duplicate identity with `data-pptx-page-role`. Add `data-pptx-role` only to structural page-frame objects whose package, page-number, or animation behavior is not already expressed by layer, placeholder, or native-object metadata; the marked element uses a stable unique `id`. See [`semantic-svg.md`](./semantic-svg.md). +**Hard rule — route-specific PowerPoint structure**: Free-design and brand-only projects use `pptx_structure.mode: flat`: write no root Master/Layout identity, `data-pptx-layer`, or `data-pptx-placeholder`; every visible object remains Slide-local. Export materializes one clean project-owned Master plus one Blank Layout from the current lock. Deck/layout template projects use `mode: structured`: every page reads its locked Master/Layout row and declares the four root identity attributes from the first draft. Do not add `data-pptx-layout-kind` or duplicate identity with `data-pptx-page-role`. Add `data-pptx-role` only to structural page-frame objects whose package, page-number, or animation behavior is not already expressed by specialized metadata; the marked element uses a stable unique `id`. See [`semantic-svg.md`](./semantic-svg.md). **Hard rule — supported PPTX route**: The only supported generated-PPTX path is `svg_output/` through the project SVG-to-DrawingML converter. Step 7.2 still generates `svg_final/` as a mandatory self-contained visual preview that may be inserted as an SVG picture. Do not treat PowerPoint's manual Convert-to-Shape operation as an authoring target or compatibility requirement. @@ -42,7 +42,7 @@ Resolve the per-page template SVG via `spec_lock.md page_layouts` (authoritative 1. **Mirror-mode template** (template's `design_spec.md` frontmatter has `replication_mode: mirror`) → see §1.1 below. The page is consumed as a **visual reference**, not as a placeholder shell. 2. `spec_lock.md page_layouts` has `P: ` for this page → inherit the structure of `templates/.svg` (already in context from §1.0). 3. `template_adherence` is present but this page has no `page_layouts` entry → stop; the template contract is incomplete. Adaptive mode must still select a reference SVG. -4. No deck/layout template at all → free design using the complete `pptx_masters` / `pptx_layouts` contract already planned in `spec_lock.md`. +4. No deck/layout template at all → flat free design: use the visual composition planned in §IX, but write no native Master/Layout mapping or SVG structure metadata. > Note: `page_layouts` disambiguates the multiple content variants a template may ship; missing mappings are contract errors. @@ -92,11 +92,11 @@ Before generating each page, output which template is used: ### 1.2 PowerPoint Master / Layout Mapping -`page_layouts` selects an input SVG prototype only on deck/layout template routes. `pptx_masters` and `pptx_layouts` always declare the output PowerPoint structure before the first page is drawn. +This section applies only to deck/layout template routes. `page_layouts` selects the input SVG prototype, `pptx_masters` / `pptx_layouts` declare unique reusable output definitions, and `page_pptx_layouts` assigns every generated page before the first page is drawn. Free-design and brand-only routes use `pptx_structure.mode: flat`, omit all four sections, skip the rest of §1.2, and keep every SVG object Slide-local. -**Hard rule — current mode only**: `pptx_structure.mode` is `structured`. Missing mode or legacy values (`baseline`, `template`, `preserve`, `flat`), `layout_strategy`, Layout-kind fields, partial mappings, and old direct placeholders must stop generation and route to [`restore-pptx-structure`](../workflows/restore-pptx-structure.md). +**Hard rule — template mode only**: A deck/layout template project uses `pptx_structure.mode: structured`. Missing mode or legacy values (`baseline`, `template`, `preserve`), `layout_strategy`, Layout-kind fields, partial mappings, and old direct placeholders must stop generation and route to [`restore-pptx-structure`](../workflows/restore-pptx-structure.md). `flat` is valid only when no deck/layout template is active. -**Hard rule — root identity**: A row `P: | | ` binds the page to a Master listed in `pptx_masters`. Put that Master key/name and Layout key/name on the root SVG. A Layout key belongs to exactly one Master and remains globally unique. +**Hard rule — root identity**: A `page_pptx_layouts` row binds the page to one key in `pptx_layouts`; that unique definition supplies its Master key, Layout picker name, and prototype source. Put the declared Master key/name and Layout key/name on the root SVG. A Layout key belongs to exactly one Master and remains globally unique. **Hard rule — atomic fixed layers**: Every `data-pptx-layer="master|layout"` visual is one direct root child that compiles to one DrawingML object. A marked `` is forbidden. When reconstructing source PPTX groups, recursively push supported transforms, paint, opacity, and z-order into atomic children. Repeat the identical ordered Master atom contract on every page using that Master and the identical ordered Layout atom contract on every page sharing that `(master, layout)` pair. @@ -193,16 +193,17 @@ Before drawing each page, look up its entry in `page_layouts` to decide which ba Do **not** invent a prototype entry, and do **not** assume a template just because `templates/` exists. For either template-adherence value, a missing or invalid `page_layouts` row is an upstream contract error. Free design is a separate deck route, never a per-page fallback. -**Per-page PowerPoint layout lookup — `pptx_layouts` section**: +**Per-page PowerPoint layout lookup — structured deck/layout templates only**: -- `pptx_structure.mode` must equal `structured`; any other or missing value routes to legacy restoration. +- When `pptx_structure.mode` is `flat`, skip this lookup and the structured scaffold below. `pptx_masters`, `pptx_layouts`, `page_layouts`, and the corresponding SVG metadata must all be absent. +- When a deck/layout template is active, `pptx_structure.mode` must equal `structured`; any other or missing value routes to legacy restoration. - Read the current page row as ` | | ` and resolve `master_key` in `pptx_masters`. Missing, malformed, or partial mappings stop before drawing. - Write matching root Master/Layout key and picker names. Do not write `data-pptx-layout-kind` or `data-pptx-page-role`. - On strict template use, the row and SVG contract match the selected prototype exactly. - On adaptive template use, retain the prototype Master. If the final composition changes fixed Layout atoms or slot topology/bounds, allocate a new key/name and update this row before completing the page. - A Layout key may repeat across non-adjacent pages only when its fixed atoms and slot contracts are identical. -**Structured-page scaffold**: +**Structured template-page scaffold**: ```xml ``` -Master/Layout atoms and slot groups are direct root children and precede ordinary content groups. Structural metadata nested inside an ordinary content group fails export. +On structured template pages, Master/Layout atoms and slot groups are direct root children and precede ordinary content groups. Structural metadata nested inside an ordinary content group fails export. Flat pages use ordinary top-level semantic groups only. **Per-page chart reference — `page_charts` section**: @@ -245,7 +246,7 @@ Before drawing each page, look up its entry in `page_charts` to decide which cha ## 3. Execution Guidelines - **Proximity**: group related elements with tight spacing; separate unrelated groups -- **Element grouping (Mandatory)**: wrap every logical Slide-local content unit — title, core-message line, each content block, card, list item, and diagram — in a top-level `` with a descriptive id. Slot `` elements are already semantic groups and are excluded from the 3–8 ordinary content-group budget. Direct Master/Layout atoms are the required exception to grouping and may never be wrapped in a layer ``. Authored native preset fragments (`preset_shape_svg.py`) already are one atomic `` each and count as one ordinary content group; keep their labels in a sibling parent ``. +- **Element grouping (Mandatory)**: wrap every logical Slide-local content unit — title, core-message line, each content block, card, list item, and diagram — in a top-level `` with a descriptive id. Flat free-design/brand-only pages use ordinary semantic groups for every logical unit. On structured template pages, slot `` elements are already semantic groups and direct Master/Layout atoms are the required exception to grouping. Authored native preset fragments (`preset_shape_svg.py`) already are one atomic `` each and count as one ordinary content group; keep their labels in a sibling parent ``. - **Spec adherence**: follow color, layout, canvas format, and typography in the spec - **Template structure**: if templates exist, inherit the visual framework - **Main-agent ownership**: SVG generation must run in the main agent (not sub-agents) — pages share upstream context for cross-page visual continuity @@ -253,8 +254,8 @@ Before drawing each page, look up its entry in `page_charts` to decide which cha - **Default — stage each page with the style's composition geometry (may override when the content genuinely calls for a plain grid)**: an SVG page is a canvas, not a DOM. Before defaulting to stacked rounded-rect cards or uniform equal columns, pick one page-scale move from the locked visual style's §1 `Composition geometry` (a bleed shape, diagonal split, oversized numeral, orbit rings, …) to stage the page's primary zone. Card grids are one option among many, not the house layout. - **Reference — image-led promotional pages (not a constraint)**: for travel, venue, product-introduction, hospitality, event, real-estate, and brochure-style decks, let images define the page skeleton before placing text. Consult [`image-layout-patterns.md`](image-layout-patterns.md) §Imported Deck Patterns and prefer patterns such as `#74` TOC image-navigation cards, `#75` asymmetric chapter banners, `#77` photo mosaic with a text cell, `#78` ambient banner + evidence photo + text panel, `#79` ribbon-header image cards, and `#80` side hero image + staggered evidence cards before falling back to plain left/right image-text splits. - **Phased batch generation** (recommended): - 1. **Visual Construction Phase**: generate all SVG pages sequentially for visual consistency. Use layout judgment for chart marks during the draft. **MUST embed plot-area markers** per §3.1 below on every chart page — coordinate calibration is a post-generation step (see [`workflows/verify-charts.md`](../workflows/verify-charts.md)) that depends on these markers — and **native object metadata** per §3.2 on every eligible data-chart page. **First-page gate (Mandatory)**: after completing the first page, run `python3 scripts/svg_quality_checker.py /svg_output/.svg` and fix every error before drawing page 2 — structural violations are systematic, and a first-page error repeated deck-wide costs a whole-deck rewrite. - 2. **Quality Check Gate**: run `python3 scripts/svg_quality_checker.py ` on `svg_output/`. Any `error` (banned features, viewBox mismatch, spec_lock drift, non-PPT-safe font, etc.) MUST be fixed on the offending page before proceeding — regenerate and re-check. Address `warning`s when straightforward. **PPTX-structure warnings (empty Layout, framing-only Layout, bare Master, duplicate layout keys) are never acknowledge-and-release**: list each one and either fix the page/lock or state per warning why the flagged state is intended (e.g. a zero-slot cover) before proceeding. Do NOT defer to after `finalize_svg.py` — finalize rewrites SVG and masks some violations. + 1. **Visual Construction Phase**: generate all SVG pages sequentially for visual consistency. Use layout judgment for chart marks during the draft. **MUST embed plot-area markers** per §3.1 below on every chart page — coordinate calibration is a post-generation step (see [`workflows/verify-charts.md`](../workflows/verify-charts.md)) that depends on these markers — and **native object metadata** per §3.2 on every eligible data-chart page. **Reach for native presets** per §3.0 as you draw each page: a block arrow, chevron, banner/ribbon, callout, standard flowchart node, or star is authored through `preset_shape_svg.py` at draw time — decided by the object's intent as you create it, never by scanning finished paths, and never committed to a bare ``/`` when a preset expresses it (a gradient fill/stroke or a pattern fill is the one paint exception — keep those ordinary SVG). **First-page gate (Mandatory)**: after completing the first page, run `python3 scripts/svg_quality_checker.py /svg_output/.svg` and fix every error before drawing page 2 — structural violations are systematic, and a first-page error repeated deck-wide costs a whole-deck rewrite. + 2. **Quality Check Gate**: run `python3 scripts/svg_quality_checker.py ` on `svg_output/`. Any `error` (banned features, viewBox mismatch, spec_lock drift, non-PPT-safe font, etc.) MUST be fixed on the offending page before proceeding — regenerate and re-check. Address `warning`s when straightforward. On a structured deck/layout template route, PPTX-structure warnings (empty Layout, framing-only Layout, bare Master, duplicate layout keys) are never acknowledge-and-release: list each one and either fix the page/lock or state per warning why the flagged state is intended (e.g. a zero-slot cover) before proceeding. Flat free-design/brand-only routes have no Master/Layout checkpoint. Do NOT defer to after `finalize_svg.py` — finalize rewrites SVG and masks some violations. 3. **Logic Construction Phase**: after SVGs pass the quality check, batch-generate speaker notes for narrative continuity. ### 3.0 Native Preset Shape Selection @@ -273,6 +274,7 @@ shape and to keep only the exceptions below as ordinary SVG. |---|---| | Plain rect / symmetric round rect / circle / ellipse | Keep the ordinary SVG primitive; it is already natively editable. | | Exact single-preset match | Call `preset_shape_svg.py render` and paste its complete stdout fragment into the current hand-authored SVG. | +| Stock shape that needs a gradient fill/stroke or a pattern fill | Keep ordinary SVG — the helper paints `none` or a solid HEX on both fill and stroke only ([`native-shape-authoring.md`](./native-shape-authoring.md) §5). | | Page-specific, compound, organic, branded, icon, or data geometry | Keep ordinary SVG path/polygon geometry. | | Similar-looking contour only | Never guess; keep ordinary SVG. | diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/semantic-svg.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/semantic-svg.md index 6a60767e..8e1ae683 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/semantic-svg.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/semantic-svg.md @@ -15,7 +15,7 @@ PPT Master uses rendering-neutral compiler hints only where ordinary SVG cannot The completed SVG remains the full visible page. Removing the metadata must not change browser rendering. Do not copy visible text, geometry, style, or asset values into metadata. -**Hard rule — structure exists at design time**: Every newly generated page declares its final Master and Layout before drawing begins. The exporter compiles this contract; it never selects, clusters, distills, or visually infers it. +**Hard rule — route boundary**: Free-design and brand-only pages use `pptx_structure.mode: flat` and omit every Master/Layout/layer/placeholder marker in this document. Deck/layout template pages declare their final Master and Layout before drawing begins; the structured exporter compiles that contract and never selects, clusters, distills, or visually infers it. **Hard rule — specialized metadata wins**: Use Master/Layout/placeholder metadata for native structure, `data-pptx-native` for chart/table reconstruction, and the imported/authored shape metadata defined in [`shared-standards.md`](./shared-standards.md) §§1.4–1.5. Do not duplicate those facts with `data-pptx-role`. @@ -23,7 +23,7 @@ The completed SVG remains the full visible page. Removing the metadata must not ## 2. Master and Layout Atoms -Master and fixed Layout visuals are atomic root children: +On structured deck/layout template routes, Master and fixed Layout visuals are atomic root children: ```xml `, nested structure marker, missing/stale id, or inconsistent shared atom contract; - a slot without positive bounds, a carrier-bound slot without exactly one compatible carrier, or a proxy binding on a non-`object` slot; - incomplete page mappings, cross-Master Layout-key reuse, or conflicting same-key Layout contracts. -Legacy SVGs using unmapped `baseline`, `preserve`, `layout_strategy: distill`, `data-pptx-layout-kind`, `distilled`, `utility`, direct atomic placeholders, or missing Master identity are not a second supported authoring contract. Run [`restore-pptx-structure`](../workflows/restore-pptx-structure.md) before generation or export. When original PPTX/native facts exist, migration restores those identities first; otherwise the main Agent explicitly derives a structure from the complete SVG pages. Export never performs that derivation. +Legacy structured/template SVGs using unmapped `baseline`, `preserve`, `layout_strategy: distill`, `data-pptx-layout-kind`, `distilled`, `utility`, direct atomic placeholders, or an incomplete Master identity are not a second supported structured contract. Run [`restore-pptx-structure`](../workflows/restore-pptx-structure.md) before generation or export. An explicit `mode: flat` free-design/brand-only project is current and intentionally has no Master identity. When original PPTX/native facts exist, migration restores those identities first; otherwise the main Agent explicitly derives structured template metadata. Export never performs that derivation. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/shared-standards.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/shared-standards.md index 3bb33135..b421870b 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/shared-standards.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/shared-standards.md @@ -7,8 +7,8 @@ Other files link here instead of restating its contracts. | Section | Owns | Strength | |---|---|---| -| §1 Required Foundation, Forbidden Features, and Conditional Interfaces | XML validity, the exhaustive structural blacklist, native line ends, image clipping, static local reuse, and imported/authored native-shape semantics | Required / Forbidden / Conditional | -| §2 Conditional Compatibility Mappings | Inline geometry and approximate group opacity | Conditional | +| §1 Required Foundation, Forbidden Features, and Conditional Interfaces | XML validity, the closed generated-authoring surface, structural blacklist, native line ends, image clipping, static local reuse, and imported/authored native-shape semantics | Required / Forbidden / Conditional | +| §2 Conditional Compatibility Mappings | Literal inline geometry and the converter-only group-opacity boundary | Conditional / Forbidden | | §3 Canvas Format Quick Reference | Pointer to the complete canvas catalog | Reference | | §4 Required Page Contract and Conditional Packaging | Complete-page authority, semantic markers, editable text/grouping, and package promotion | Required / Conditional | | §5 Workflow Authority | Pointer to the serial post-processing/export procedure | Workflow pointer | @@ -20,7 +20,7 @@ Other files link here instead of restating its contracts. | Capability family | Available authoring vocabulary | Detail | |---|---|---| -| Color and transparency | CSS alpha colors; fill, stroke, text, picture, stop, element, and group opacity | §2.2, §6.2 | +| Color and transparency | CSS alpha colors; fill, stroke, text, picture, stop, and element opacity; converter-only group-opacity compatibility | §2.2, §6.2 | | Gradients and paint | Linear/radial fills, transparent stops, gradient text, gradient strokes, and preset patterns | §6.3, §7 | | Depth and light | Soft/colored/directional shadow, glow, layered-geometry fallback, and paper-layer elevation | §6.4 | | Image treatment | Directional scrim, bottom fade, vignette, spotlight, brand wash, picture fading, and glass-like surfaces | §1.2, §6.5 | @@ -51,6 +51,17 @@ Other files link here instead of restating its contracts. - **Reference — not a constraint** passages expose capabilities and recipes; they do not require every page or visual style to use them. - The locked `visual_style` controls whether and how strongly a compatible effect is used. It never expands the technical boundary. +**Hard rule — generated authoring is fail-closed**: `svg_output/` and reusable +template SVGs may use only properties and conditional interfaces explicitly +listed in this file. `svg_quality_checker.py` rejects unknown inline visual +properties and incomplete conditional contracts before export. + +**Hard rule — compatibility is not authoring permission**: the converter may +retain broader read compatibility for imported or historical SVG, including +normalization and documented approximation. That compatibility does not add a +feature to the generated-authoring surface. Do not remove converter support +merely to enforce a narrower authoring contract. + **Hard rule — one-way fidelity vocabulary**: the labels above describe the `svg_output/` → generated PPTX path. They do not promise reconstruction of the original SVG syntax, `` graph, `` structure, path commands, or @@ -92,9 +103,25 @@ One offending character invalidates the file and aborts export. | ` - + ``` @@ -382,14 +408,19 @@ only for literal declarations in an element's own `style` attribute; PPT Master does not compute CSS cascade or custom properties. Root canvas authority remains the `viewBox`, regardless of root `` compatibility width/height values. -### 2.2 Group Opacity Is Approximate +### 2.2 Group Opacity Is Converter-Only Compatibility -`...` maps the group alpha onto each descendant shape, -text run, picture, and supported -shadow/glow effect. Nested group and child opacity values multiply. Overlapping -children may differ from SVG isolated-group compositing because DrawingML has no -equivalent group-alpha model. With `--native-objects`, transparent native -table/chart markers are rejected; omit that flag to export their SVG fallback. +**Forbidden — generated group opacity**: Do not author `` or +inline group `opacity` below `1` in `svg_output/` or reusable templates. Put the +required alpha on each descendant paint, text run, picture, or supported effect. +The quality checker rejects generated group opacity because DrawingML has no +isolated group-alpha model and overlapping descendants produce a different +result. + +The converter retains direct-read compatibility for historical/imported SVG by +multiplying group alpha into descendants. That path is `Approximate`; nested +group/child alpha multiplies, and `--native-objects` rejects transparent native +table/chart markers. It is not an authoring permission. --- @@ -414,8 +445,7 @@ table/chart markers are rejected; omit that flag to export their SVG fallback. ### 4.1 Semantic SVG Marker Contract -Semantic markers are minimal compiler hints orthogonal to native SVG semantics. -Root Master/Layout identity, atomic layer elements, grouped slots, and native-object metadata are authoritative and read first. Every new page carries its final structured contract from the start of SVG authoring. Add `data-pptx-role` only when no specialized marker expresses the required page-frame behavior; the element also uses a stable unique `id`. Do not classify ordinary page content or move visible facts out of SVG attributes/text into metadata. See [`semantic-svg.md`](semantic-svg.md) for the canonical vocabulary and examples. +Semantic markers are minimal compiler hints orthogonal to native SVG semantics. Free-design and brand-only pages use flat export and omit Master/Layout/layer/placeholder markers. On deck/layout template routes, root Master/Layout identity, atomic layer elements, grouped slots, and native-object metadata are authoritative and read first; each page carries its final structured contract from the start of SVG authoring. Add `data-pptx-role` only when no specialized marker expresses the required page-frame behavior; the element also uses a stable unique `id`. Do not classify ordinary page content or move visible facts out of SVG attributes/text into metadata. See [`semantic-svg.md`](semantic-svg.md) for the canonical vocabulary and examples. - **Canvas authority**: `viewBox` MUST match the selected canvas dimensions. Root `width` and `height` are optional and do not override it. Root `` @@ -437,16 +467,16 @@ These forms are needed only when the stated PPT behavior matters: | One editable PPT text frame with mixed inline formatting | Put the logical line in one `` with non-positional `` children. A `` with `x`/`y`/`dy` starts a new positioned line. Evenly `dy`-stacked lines that repeat the parent ``'s `x` stay in one frame: equal effective `font-size` may flow in the current paragraph, while a font-size change, list marker, or accepted larger gap starts a new paragraph. An unmergeable gap or mismatched `x` flattens to separate frames. Separate `` elements stay valid when separate frames are intended. | | Stable object grouping or object-level animation anchor | Wrap the intended object in ``. Content grouping is **mandatory** per §4.3 — a top-level `` is also the animation anchor; it is not an optional convenience. | | Native PowerPoint background promotion | Use a direct, full-canvas, solid `` without transform, filter, clip, rounding, or visible stroke. Other SVG backgrounds remain ordinary slide shapes. Template routes add the ownership metadata in §7. | -| Reusable free-design PowerPoint Layout | Strategist declares the Master roster and complete page-to-Layout map before drawing. Executor writes the root identities, atomic fixed layers, and grouped slots while authoring each page. Export compiles only those declarations. | -| Reusable template-based PowerPoint Layout | Select one complete input SVG per page in `page_layouts` and declare the output Master/Layout mapping at planning time. Strict preserves the prototype contract; adaptive retains its Master and may assign a new explicit Layout key during page authoring. Non-mirror skin follows `spec_lock`. | +| Free-design / brand-only PowerPoint structure | Use `pptx_structure.mode: flat`. Keep every represented object Slide-local; export materializes one clean project-owned Master plus one Blank Layout from the current lock, removes stock content placeholders/Layout inventory, and retains only the standard date/footer/slide-number capability hooks. Do not author Master/Layout identities, layers, or placeholder slots. | +| Reusable template-based PowerPoint Layout | Select one complete authoring SVG per page in `page_layouts`, declare each unique Master/Layout definition once, and assign pages through `page_pptx_layouts`. Strict preserves the prototype contract; adaptive retains its Master and may define and assign a new explicit Layout key during page authoring. Non-mirror skin follows `spec_lock`. | **Hard rule — supported shape conversion**: Every PPT editability claim in this specification refers to the project converter reading `svg_output/` and emitting native DrawingML. `svg_final/` is a self-contained visual preview that may be inserted into PowerPoint as an SVG picture. PowerPoint's manual Convert-to-Shape operation is unsupported; do not narrow the authoring contract to its undocumented SVG subset. ### 4.3 Element Grouping (Mandatory) -Wrap logically related Slide-local elements in top-level `` groups. This is **required on every generated page**, not an optional convenience: it produces real PowerPoint groups in the exported PPTX and gives each content unit a stable animation anchor. Plain `` is the normal grouping primitive; `` additionally maps to the per-descendant alpha approximation in §2.2. Direct atomic Master/Layout elements are the required exception and may never be layer groups. A top-level slot `` is already a semantic group and is excluded from the ordinary content-group budget. +Wrap logically related Slide-local elements in top-level `` groups. This is **required on every generated page**, not an optional convenience: it produces real PowerPoint groups in the exported PPTX and gives each content unit a stable animation anchor. Plain `` is the grouping primitive; keep alpha on individual descendants per §2.2. Flat free-design/brand-only pages use only ordinary semantic groups. On structured template pages, direct atomic Master/Layout elements are the required exception and a top-level slot `` is already a semantic group. -**Semantic-group rule**: apart from atomic Master/Layout objects and the optional Slide background, direct Slide content uses semantic groups. Aim for **3–8 ordinary top-level content `` groups per slide**; slot groups and structural atoms are excluded. Each ordinary group becomes one entrance step under the chosen animation trigger. Leaving Slide-local titles, body lines, list items, cards, or decorative clusters as ungrouped top-level atoms is a contract violation. +**Semantic-group rule**: direct Slide content uses semantic groups. Aim for **3–8 ordinary top-level content `` groups per slide**; on structured template pages, slot groups and atomic Master/Layout objects are excluded. Each ordinary group becomes one entrance step under the chosen animation trigger. Leaving Slide-local titles, body lines, list items, cards, or decorative clusters as ungrouped top-level atoms is a contract violation. **Structural atoms and slots are excluded automatically.** `data-pptx-layer` and `data-pptx-placeholder` semantics are read first; otherwise explicit `data-pptx-role` values (`background`, `decoration`, `header`, `footer`, `chrome`, `watermark`, `page-number`, `logo`) mark Slide-local static framing (§4.1, [`semantic-svg.md`](semantic-svg.md)). A normal slot group has exactly one direct compatible carrier; several drawing atoms require the explicit composite `object` proxy fallback. Native chart/table carrier groups retain their specialized §7 contract. @@ -528,22 +558,23 @@ without `#` is invalid. | Element `opacity` | Alpha compiled into supported paint/effect channels | `Native-normalized` | | `` | Picture `` | `Native-stable` | | `` | Per-stop gradient alpha | `Native-stable` | -| `` | Alpha multiplied into each supported descendant shape, text run, picture, and effect | `Approximate` | +| `` | Direct-converter compatibility only; generated SVG authoring is forbidden | `Approximate`; §2.2 | | Pattern child/color alpha | Preset-pattern foreground/background alpha | Conditional; §7 | ```text effective fill alpha -= color alpha × element opacity × fill-opacity × ancestor group opacity += color alpha × element opacity × fill-opacity ``` +The converter-only historical path may additionally multiply ancestor group +opacity; generated SVG never depends on that approximation. + **Hard rule — alpha grammar**: write `opacity`, `fill-opacity`, -`stroke-opacity`, and `stop-opacity` as finite numbers from `0` to `1`. +`stroke-opacity`, `stop-opacity`, and `flood-opacity` as finite unitless numbers +from `0` to `1`. `fill="transparent"` / `stroke="transparent"` become no fill/line; use a color plus alpha when a painted transparent layer must remain represented. Group -alpha is not isolated compositing, so overlapping descendants may differ from -the browser. Transparent groups around `data-pptx-native` chart/table markers -cannot be promoted under `--native-objects`; export the SVG fallback or remove -the group opacity. +opacity below `1` is forbidden in generated SVG; assign alpha to descendants. --- @@ -598,12 +629,12 @@ Filters are native-effect metadata, not a general pixel-filter surface. | Classification | Meaningful non-zero offset → one outer shadow; zero/no offset → one glow | | Fidelity | `Approximate`; one filter becomes one DrawingML effect | -Flood/color alpha, linear `feFuncA slope`, element opacity, and ancestor opacity -multiply. Native export does not preserve filter-region, `in/in2/result`, merge -order, or composite topology. Other primitives, multiple independent effects, -filters on `` / `` / unsupported targets are forbidden. Do not -put a filter on a multi-element ``; apply it to supported objects or use -explicit layers. +Flood/color alpha, linear `feFuncA slope`, and element opacity multiply. The +converter-only historical path may also multiply ancestor group opacity. +Native export does not preserve filter-region, `in/in2/result`, merge order, or +composite topology. Other primitives, multiple independent effects, filters on +`` / `` / `` / unsupported targets are forbidden; apply the +effect to supported objects or use explicit layers. ```xml @@ -747,7 +778,7 @@ modes, generated effects, and text-image knockouts are outside editable text. | Positive scale / negative mirror | Geometry/image only; explicit pivot; `Native-normalized` | | `matrix(a b c d e f)` | Geometry/image only; transformed axes finite, non-zero, orthogonal; excludes rounded rects; `Native-normalized` | | Source order | Back-to-front PPT z-order; `Native-stable` | -| `` | Descendant alpha; `Approximate`, §2.2 | +| `` | Converter-only historical compatibility; forbidden in generated SVG, §2.2 | | Local `` | §1.3 compile-time reuse; `Native-normalized` | Set text size/position directly; do not scale or general-matrix text. `skewX`, @@ -971,7 +1002,8 @@ the tile's arbitrary geometry. Use this interface only when that preset mapping is intended. `data-pptx-pattern=""` is required to select the intended preset from -the enum below; without it, export falls back to `ltUpDiag`. +the enum below. The converter retains an `ltUpDiag` fallback for historical +input, but generated authoring without the annotation fails quality check. Pattern colors may come from importer metadata (`data-pptx-fg` / `data-pptx-bg`) or from the pattern's child paint. Without metadata, the first @@ -991,8 +1023,8 @@ itself is never used as a repeatable tile. | Checks & confetti | `smCheck` · `lgCheck` · `smConfetti` · `lgConfetti` | | Decorative | `horzBrick` · `diagBrick` · `weave` · `plaid` · `trellis` · `zigZag` · `wave` · `sphere` · `divot` · `shingle` · `solidDmnd` · `openDmnd` · `dotDmnd` | -`svg_quality_checker.py` warns when the annotation is missing and errors when -the preset is outside this enum. +`svg_quality_checker.py` errors when a referenced pattern lacks the annotation, +uses `patternTransform`, or names a preset outside this enum. ### Native PPTX Table / Chart Markers (Opt-in) @@ -1341,11 +1373,11 @@ defaults to `bottom` and accepts `top`, `left`, or `right`. **Forbidden — native marker transforms**: Do not rotate, skew, or matrix-transform native table/chart marker groups. Translate / scale is accepted; complex transforms fail export because PowerPoint native table/chart frames do not preserve arbitrary SVG transforms. -### Structured Layout Routing +### PPTX Structure Routing -Every new SVG project has one deterministic route: `pptx_structure.mode: structured`. `spec_lock.md` contains a complete Master roster and one page-to-Master/Layout row before the first page is drawn. Free design defaults to one Master. `standard` / `fidelity` templates use their newly authored contract; mirror templates use the restored source identities and parentage expressed through the same explicit interface. +Every new SVG project declares one deterministic route. Free-design and brand-only projects use `pptx_structure.mode: flat`, omit `pptx_masters` / `pptx_layouts` / `page_pptx_layouts` / `page_layouts`, and author no Master/Layout/layer/placeholder metadata. Export keeps all represented content Slide-local while materializing one clean project-owned Master plus one Blank Layout from the current color/typography lock; stock content placeholders and unused built-in Layouts are removed, while the standard date/footer/slide-number capability hooks remain. Deck/layout template projects use `mode: structured`; `standard` / `fidelity` templates use their authored contract, while mirror templates use restored source identities and parentage. -**Hard rule — no structure inference**: Export does not assign Layout families, promote repeated chrome, cluster pages, infer placeholders, or repair missing metadata. It compiles only the declared root identities, atomic fixed layers, and slot groups. Legacy or unmapped projects must run [`restore-pptx-structure`](../workflows/restore-pptx-structure.md) first. +**Hard rule — no structure inference**: Flat export performs no promotion or deduplication; every object stays Slide-local. Structured template export compiles only declared root identities, atomic fixed layers, and slot groups—it does not assign Layout families, cluster pages, infer placeholders, or repair missing metadata. Legacy structured/template projects must run [`restore-pptx-structure`](../workflows/restore-pptx-structure.md) first. **Layout reuse**: Reuse one Layout key only when its ordered fixed Layout atoms and slot ids/types/effective indices/default bounds/binding modes are identical. Different wording, data, imagery, crop, or Slide-local carrier geometry does not create a new Layout. A genuinely different reusable contract gets a new key even when both pages are semantically `content`. @@ -1355,26 +1387,30 @@ Every new SVG project has one deterministic route: `pptx_structure.mode: structu ### Explicit PPTX Master / Layout / Placeholder Metadata -**Trigger**: Every newly generated SVG page uses this interface. `spec_lock.md` declares `pptx_structure.mode: structured`, a complete `pptx_masters` roster, and one `pptx_layouts` row per page before authoring begins. Template routes additionally keep `page_layouts` as input-prototype provenance. +**Trigger**: This explicit metadata interface applies only to deck/layout template projects and structure-restoration workflows. `spec_lock.md` declares `pptx_structure.mode: structured`, complete unique `pptx_masters` / `pptx_layouts` rosters, one `page_pptx_layouts` assignment per generated page, and `page_layouts` as authoring-prototype provenance. Flat free-design/brand-only SVGs use none of these metadata fields. -**Project lock**: A Master row is `: `. A page row is `P: | | `. The SVG root values MUST match those rows. A Layout key belongs to exactly one Master and must be globally unique. Reuse one key only when pages share identical ordered Layout atoms and slot ids/types/effective indices/default bounds/binding modes. Every structured route requires numeric `spec_lock.md` typography `title` / `body` rows. +**Project lock**: A Master row is `: `. A unique Layout row is `: | | `, where the source is a generated `P` or installed `template:`. A page assignment is `P: ` under `page_pptx_layouts`. The SVG root values MUST match the assigned definition. A Layout key belongs to exactly one Master and must be globally unique. Reuse one key only when prototypes share identical ordered Layout atoms and slot ids/types/effective indices/default bounds/binding modes. An unused Layout uses a template SVG source and remains registered without a published carrier slide. Every structured route requires numeric `spec_lock.md` typography `title` / `body` rows. **Template behavior**: Strict preserves the selected prototype's declared Master/Layout/slot contract. Adaptive retains its Master and may allocate a new Layout key/name only when fixed Layout atoms or slot topology/bounds change; update the lock during authoring. Mirror-created prototypes preserve restored source identity, literal paint, typography, effects, atomic geometry, and referenced assets. `standard` / `fidelity` never make source topology authoritative; mirror does not synthesize a replacement topology. -**Master text-style contract**: Structured export maps the -locked `title` size to every `a:defRPr` in Master `p:titleStyle`, and map the -locked `body` size to every level in both `p:bodyStyle` and `p:otherStyle`. +**Master text-style contract**: Flat and structured export map the +locked `title` size to every `a:defRPr` in Master `p:titleStyle`. Level 1 in +both `p:bodyStyle` and `p:otherStyle` uses the locked `body` size; levels 2–9 +use a deterministic descending hierarchy from `15/16` through `8/16` of that +size, rounded to 0.5 pt and floored at the smaller of 8 pt or the body size. +Existing per-level indentation and bullet properties remain unchanged. | Master style | Locked source | XML field changed | |---|---|---| | `p:titleStyle` | `typography.title` | Every `a:defRPr@sz` | -| `p:bodyStyle` | `typography.body` | Every `a:defRPr@sz` | -| `p:otherStyle` | `typography.body` | Every `a:defRPr@sz` | +| `p:bodyStyle` | `typography.body` | Level 1 plus derived level 2–9 `a:defRPr@sz` | +| `p:otherStyle` | `typography.body` | Level 1 plus derived level 2–9 `a:defRPr@sz` | **Hard rule — narrow scope**: This Master update changes only Master -`p:txStyles//a:defRPr@sz`. It does not rewrite direct run sizes on generated -slides, so the initial slide rendering remains controlled by the authored SVG. -Missing `title` or `body` rows fail structured export. +`p:txStyles//a:defRPr@sz`; it preserves level indentation, bullet, margin, and +paragraph settings. It does not rewrite direct run sizes on generated slides, +so the initial slide rendering remains controlled by the authored SVG. Missing +`title` or `body` rows fail flat or structured export. **Layout level-one text-default contract**: For every text-bearing placeholder whose first prototype run has a direct `a:rPr@sz`, explicit Layout export copies that @@ -1400,7 +1436,7 @@ prototype size remain unchanged. | `data-pptx-placeholder-binding="proxy"` | composite `object` slot `` only | Keeps the visible group ordinary and creates one hidden transparent binding proxy | | `data-pptx-editable="false"` | master/layout element or slide background | Declares intentional editing outside ordinary slide content | -**Hard rule — explicit only**: Structured export never promotes visually similar content by inference. Every SVG requires the four root Master/Layout identity attributes. Every Master/Layout atom and slot requires a unique stable `id` and is a direct root child. Layouts with zero slots are valid. `data-pptx-layout-kind`, `distilled`, and `utility` are legacy metadata and fail the current contract. +**Hard rule — explicit only**: On a structured deck/layout template route, every SVG requires the four root Master/Layout identity attributes. Every Master/Layout atom and slot requires a unique stable `id` and is a direct root child. Layouts with zero slots are valid. `data-pptx-layout-kind`, `distilled`, and `utility` are legacy metadata and fail the structured contract. Flat free-design/brand-only pages omit the entire interface. **Layer order**: Author the SVG in PowerPoint paint order: Master background, Layout background, optional Slide background, remaining Master atoms, remaining Layout atoms, @@ -1445,15 +1481,14 @@ Because an omitted `p:ph@idx` has the effective value `0`, an omitted-index title reserves `0`; no other placeholder on that Layout may use the same effective index. -**Slot prototype**: The first slide using a Layout key supplies that Layout's placeholder formatting. `data-pptx-placeholder-bounds` supplies the reusable default frame and is mandatory on every slot. Derive it from +**Slot prototype**: The prototype source declared by the unique Layout definition supplies that Layout's placeholder formatting. `data-pptx-placeholder-bounds` supplies the reusable default frame and is mandatory on every slot. Derive it from the intended design zone, column, panel inset, safe area, or picture frame — never from text length, glyph width, line count, or a tight content bounding box. Repeat the same slot ids/types/effective indices/default bounds/binding modes on every slide using that Layout. The Layout owns the reusable `p:ph`; normal visible carriers keep a matching Slide binding so approved rendering stays identical. A composite `object` proxy adds one hidden transparent binding shape to suppress empty inherited placeholder paint. Bounds define the Layout default only; actual Slide content and local carrier geometry may differ. **Final-package read-back gate**: After writing a temporary structured PPTX and before publishing it, export reopens the package and -verifies that -each Slide targets exactly one Layout, one layout key always resolves to the -same part, different keys do not collapse onto one part, and every Layout is +verifies that each published Slide targets exactly one Layout, one Layout key always resolves to the +same part, different keys do not collapse onto one part, and every declared Layout—including one unused by all published Slides—is registered through its Master and the Presentation. Physical Slide/Layout/ Master part rosters, their content-type overrides, and their Presentation/ Master registrations must be exact. It also verifies the Layout picker name, @@ -1480,9 +1515,9 @@ video or audio media from a decorative SVG group. ### Legacy Structure Migration Boundary -Existing projects or packages that carry `native_structure.json` / `source_template.pptx`, `pptx_structure.mode: baseline|template|preserve`, `layout_strategy`, `data-pptx-layout-kind`, `distilled` / `utility`, direct atomic placeholders, or no root Master identity must run [`restore-pptx-structure`](../workflows/restore-pptx-structure.md) before generation or export. +Existing structured/template projects or packages that carry `native_structure.json` / `source_template.pptx`, `pptx_structure.mode: baseline|template|preserve`, `layout_strategy`, `data-pptx-layout-kind`, `distilled` / `utility`, direct atomic placeholders, or an incomplete root Master identity must run [`restore-pptx-structure`](../workflows/restore-pptx-structure.md) before generation or export. A project explicitly declaring `pptx_structure.mode: flat` is the current free-design/brand-only route and does not require restoration merely because it has no Master/Layout metadata. -When original PPTX/native facts exist, migration preserves the reachable source Master roster, Layout parent relationships and picker names, placeholder type/index/bounds, and visible supported geometry while normalizing the package into the explicit contract. Source Master/Layout groups are recursively flattened into atomic SVG elements. The current structured roster cannot materialize a source Layout that no output page references, or a Master reachable only through such Layouts; stop and report those identities instead of silently dropping them or inventing a carrier page. A subsequent `create-template` run treats the result according to its selected mode: `standard` / `fidelity` author a new topology, while mirror keeps the restored source topology only when the source graph satisfies that reachability boundary. When no native facts exist, the main Agent explicitly derives a structured contract from the complete SVG pages; the exporter never performs that derivation. +When original PPTX/native facts exist, migration preserves the complete source Master roster, Layout parent relationships and picker names, placeholder type/index/bounds, and visible supported geometry while normalizing the package into the explicit contract. Source Master/Layout groups are recursively flattened into atomic SVG elements. Create one reusable prototype SVG for every retained Layout, including Layouts unused by source slides; downstream `pptx_layouts` definitions can register those prototypes without manufacturing generated pages. A subsequent `create-template` run treats the result according to its selected mode: `standard` / `fidelity` author a new topology, while mirror keeps the restored source topology. When no native facts exist, the main Agent explicitly derives a structured contract from the complete SVG pages; the exporter never performs that derivation. --- diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist.md index a6f9c588..f40c0982 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist.md @@ -98,7 +98,7 @@ The deck's **visual aesthetic** — shape language, decoration density, whitespa Write the locked value to `spec_lock.md` `- visual_style:` and the rationale to `design_spec.md`. Executor loads only that one visual-style file. -> **Template vs preset**: a style mention may sound like a template name ("academic style" vs the `academic_defense/` template directory). Step 3 only triggers on an explicit template directory path supplied by the user — bare names and style words never copy templates; they map to a visual-style preset here. If a template was triggered upstream, its files are already in `/templates/` and its fused design_spec governs. +> **Template vs preset**: a style mention and a template name remain different inputs ("minimalist" vs the `presentation_core/` template directory). Step 3 only triggers on an explicit template directory path supplied by the user — bare names and style words never copy templates; they map to a visual-style preset here. If a template was triggered upstream, its files are already in `/templates/` and its fused design_spec governs. **Legacy template boundary**: A template containing `native_structure.json`, `source_template.pptx`, missing root Master identity, direct atomic placeholders, or old `baseline` / `preserve` / distillation metadata must run [`restore-pptx-structure`](../workflows/restore-pptx-structure.md) before Step 3. Do not plan against a legacy compatibility contract. @@ -689,6 +689,8 @@ The catalog covers **both data charts and structural information designs**. A "m The most common Strategist failure mode is missing the structural half — treating "chart" as "numeric chart only" and leaving team / agenda / principles / journey pages as text-only when a template would fit. Read the catalog with both lenses. +**Flag native-preset candidates on §VII pages.** For any page row already listed in §VII (including `no-template-match` rows), when its content also calls for a literal stock PowerPoint shape — a chevron, block arrow, standard flowchart node, callout, banner, or star (judged from the page plan, not from a template's name or drawing) — append a candidate note to that page's `Usage`, e.g. `…existing usage…; native-preset candidate: chevron; Executor applies executor-base §3.0`. This primes the Executor at plan-read time without deciding for it: the Executor still selects the exact preset, frame, and paint at draw time via [`executor-base.md`](./executor-base.md) §3.0, or keeps ordinary SVG when that section's exceptions apply. Pages with no §VII row rely on the Executor's §3.0 judgment at draw time. + > **Reading is mandatory; the catalog is a starting point, not a copy target.** > - Fully read `templates/charts/charts_index.json` **before drafting the Strategist confirmation stage** — the read happens up front, not when you sit down to write Section VII. The file contains `meta` + `charts..summary` only; each `summary` is a selection rule (`"Pick for … Skip if …"`), not a description. There is **no category, quickLookup, or keyword index** — selection is done by semantically matching each page's content shape against all 76 summaries in one pass. > - Not every page needs a chart. When a page's information structure matches a catalog entry, **use that template as a structural starting point** — keep the visualization type and core layout logic, then adapt composition, density, color, decoration, and accompanying elements to fit this deck's content and visual tone. Free adjustment is encouraged; what is forbidden is (a) generating without reading the catalog, and (b) blind verbatim mimicry that ignores the page's actual content weight. @@ -845,18 +847,20 @@ This is what makes the axis meaningful: a `presentation` deck and a `text` deck 1. Read reference template: `templates/design_spec_reference.md` 2. Generate complete spec from scratch based on analysis 3. Save to: `projects/.../design_spec.md` -4. **Generate execution lock**: read `templates/spec_lock_reference.md` and produce `projects/.../spec_lock.md` — a compact, machine-readable form of the color / typography / icon / image / **page_rhythm** / **page_layouts** / **page_charts** / **pptx_masters** / **pptx_layouts** decisions above. Master/Layout structure is part of this planning contract before the first SVG. This file is what the Executor re-reads before every page (see [executor-base.md](executor-base.md) §2.1). The values in `spec_lock.md` MUST exactly match the decisions recorded in `design_spec.md`; if they ever diverge, `spec_lock.md` wins and `design_spec.md` should be treated as historical narrative. +4. **Generate execution lock**: read `templates/spec_lock_reference.md` and produce `projects/.../spec_lock.md` — a compact, machine-readable form of the color / typography / icon / image / **page_rhythm** / **page_charts** and route-specific PowerPoint structure decisions above. Within the PowerPoint structure portion, free-design and brand-only routes write only `pptx_structure.mode: flat`; deck/layout template routes additionally write `page_layouts`, `page_pptx_layouts`, `pptx_masters`, and `pptx_layouts`. This file is what the Executor re-reads before every page (see [executor-base.md](executor-base.md) §2.1). The values in `spec_lock.md` MUST exactly match the decisions recorded in `design_spec.md`; if they ever diverge, `spec_lock.md` wins and `design_spec.md` should be treated as historical narrative. - **page_rhythm is mandatory**: Based on the page list in §IX Content Outline, assign each page one of `anchor` / `dense` / `breathing` (see `spec_lock_reference.md` for the full vocabulary). This is what breaks the uniform "every page is a card grid" feel — without it the Executor defaults all pages to `dense`. - **Rhythm follows narrative, not quota**: `breathing` pages mark natural pauses — chapter transitions, standalone emphasis (hero quote / big number), SCQA bridges. Dense decks may legitimately be all `dense`. **Do NOT invent filler pages** ("Thank you", empty dividers) to pad rhythm — every `breathing` page must say something independent. Delivery purpose biases the overall lean (`presentation` toward more `anchor` / `breathing`, `text` toward `dense`; see §6.1) — a bias, never a quota. - **Cover impact is mandatory**: Page `P01` is the deck's first visual contract, not a generic title slide. In `design_spec.md §IX`, add a `Cover impact` line for `P01` that names one concrete hook and one concrete composition strategy. Use the source's strongest available signal: a provocative core claim, object / scene metaphor, hero number, founder / product / audience moment, or a distilled conflict. Pair it with one concrete composition strategy — such as `full-bleed image + floating title`, `typographic poster`, `hero object`, `data hook`, `editorial scene`, `high-contrast abstract geometry`, or a fresh composition the deck's subject suggests (these are starting points, not the allowed set). If no external or AI image is available, still specify a native-SVG visual hook; do not fall back to "title + subtitle + decorative background". (Beautify / template-fill keep the source cover verbatim — this rule does not apply on those preservation paths.) - **Cover rhythm lock**: `P01` remains `anchor` in `spec_lock.md page_rhythm`, but its §IX `Cover impact` must prevent content-page patterns. Do not plan multi-card grids, agenda-like bullets, or equal-weight columns on the cover unless a template explicitly requires that structure, or a preservation path (beautify / template-fill) is transcribing the source cover verbatim. - **Closing impact (only when the deck closes)**: the deck's last page is its final visual contract — the strongest impression after the cover. When the deck genuinely lands on a conclusion / call-to-action / final-takeaway page, give it a `Closing impact` line in §IX: name the one thing the audience should leave with (a distilled takeaway, a forward call, a memorable restatement of the core claim) + one composition that delivers it — never a generic "Thank you" / contact-only slide or a centered-title reprise of the cover. **Do NOT invent a closing page to satisfy this** — the filler-page ban above still holds; apply it only to the page where the deck actually resolves. Same exemptions as the cover: skip on template / beautify / template-fill preservation paths. - - **pptx_structure is mandatory**: Every new project writes `mode: structured`. Free design and brand-only routes default to one Master; add another only when the design genuinely needs it. Deck/layout templates also record `template_adherence: strict|adaptive`. Do not write `baseline`, `template`, `preserve`, `flat`, `layout_strategy`, or Layout-kind rows into a new project. - - **Master roster**: Write one `pptx_masters` row per Master as `: `. For a template, copy the restored prototype roster. For free design, define stable deck-wide background/chrome atoms at planning time; Master visuals are root-level atomic elements and may never be ``. - - **pptx_layouts (native output contract)**: Write exactly one row per page before generation as ` | | `. Plan semantic Layout families from the outline and reuse a key only when fixed Layout atoms plus slot ids/types/indices/bounds/binding modes are identical. Name each key after its composition (`timeline-spine`, `kpi-band-trio`, `content-image-right`), never after a PowerPoint stock role or the page's topic. A Layout may intentionally have zero slots; never manufacture an empty `utility` kind or full-page fake slot. **Self-check before writing the section**: compare distinct keys against the distinct compositions in §IX. Distinct compositions collapsing into a handful of stock-role keys (`cover` / `title-content` / `section`) means pages were clustered by role; one shared skeleton splitting into per-topic keys (`allocation-fengqing` / `allocation-luoping`) means pages were split by topic. Both misstate the roster — re-derive from composition. - - **Slot planning**: Each reusable slot is a direct root `` with `data-pptx-placeholder`, positive design-zone bounds, and exactly one compatible direct carrier. Bounds come from the intended safe area, column, panel inset, or media frame—not sample text ink. A genuinely composite region may use only the explicit `object` + `proxy` downgrade. - - **Adaptive refinement boundary**: The initial mapping is complete, not provisional. If actual adaptive construction genuinely changes reusable framing or slot topology/bounds, Executor creates a new Layout key and updates `spec_lock.md` while authoring that first page. It never mutates a reused contract silently. Export only compiles declared structure and never discovers or clusters Layouts. - - **page_layouts (deck/layout templates only)**: Add one `P: ` row for every page. This is the complete input-prototype mapping. Strict preserves that SVG's structural contract; adaptive keeps its Master and may explicitly assign a new output Layout identity during page authoring. Omit the whole section for free-design and brand-only routes. + - **pptx_structure is mandatory**: Free-design and brand-only routes write `mode: flat`. Deck/layout template routes write `mode: structured` plus `template_adherence: strict|adaptive`. Do not write legacy `baseline`, `template`, `preserve`, `layout_strategy`, or Layout-kind rows into a new project. + - **Flat-route boundary**: With `mode: flat`, omit `pptx_masters`, `pptx_layouts`, `page_pptx_layouts`, and `page_layouts`. Do not plan native Master/Layout families or reusable placeholder slots. Every generated SVG object remains Slide-local: omit root Master/Layout identity, `data-pptx-layer`, and `data-pptx-placeholder*` metadata. Export materializes one clean project-owned Master plus one Blank Layout from the current color/typography lock, removes stock content placeholders/Layout inventory, and retains only the standard date/footer/slide-number capability hooks. + - **Master roster (deck/layout templates only)**: Write one `pptx_masters` row per Master as `: ` and copy the restored prototype roster. Master visuals are root-level atomic elements and may never be ``. + - **pptx_layouts (deck/layout template reusable roster)**: Write every unique reusable Layout once as `: | | `. Copy the installed template roster with `template:` sources, including Layouts no generated page currently uses. A genuinely new adaptive Layout uses its first generated `P` as the source. Reuse a key only when fixed Layout atoms plus slot ids/types/indices/bounds/binding modes are identical. Name authored keys after composition (`timeline-spine`, `kpi-band-trio`, `content-image-right`), never after page topic. A Layout may intentionally have zero slots; never manufacture an empty `utility` kind or full-page fake slot. + - **page_pptx_layouts (deck/layout template page assignment)**: Write exactly one `P: ` row per generated page. The key must exist in `pptx_layouts`; Master and picker name are inherited from that unique definition. **Self-check before writing the section**: compare distinct assigned keys against distinct compositions in §IX. Distinct compositions collapsing into a handful of role-only keys means pages were clustered by topic label; one shared skeleton splitting into topic-specific keys means pages were split by content wording. Both misstate the roster. + - **Slot planning (deck/layout templates only)**: Each reusable slot is a direct root `` with `data-pptx-placeholder`, positive design-zone bounds, and exactly one compatible direct carrier. Bounds come from the intended safe area, column, panel inset, or media frame—not sample text ink. A genuinely composite region may use only the explicit `object` + `proxy` downgrade. + - **Adaptive refinement boundary (deck/layout templates only)**: The initial definitions and assignments are complete, not provisional. If actual adaptive construction genuinely changes reusable framing or slot topology/bounds, Executor creates one new `pptx_layouts` definition sourced from that page and updates its `page_pptx_layouts` assignment while authoring the first page. It never mutates a reused contract silently. Export only compiles declared structure and never discovers or clusters Layouts. + - **page_layouts (deck/layout templates only)**: Add one `P: ` row for every page. This is the complete authoring-input prototype mapping. Strict preserves that SVG's structural contract; adaptive keeps its Master and may explicitly define and assign a new output Layout identity during page authoring. Omit the whole section for free-design and brand-only routes. - **page_charts (write only for chart pages that match a catalog template)**: For each page in `design_spec.md §VII` whose `reference template path` points to `templates/charts/.svg`, add `P: `. Pages with `no-template-match` in §VII MUST NOT appear here (Executor would look for a non-existent reference). If the deck has no data-visualization pages, omit the section. - **Hard rule**: Use both `page_layouts` and `page_charts` only with a compatible template shell. For a chart page without an exact roster match, adaptive mode selects the closest neutral input prototype and assigns an explicit output Layout key in the planning map; strict mode must select an existing compatible Layout or revise the outline. Never omit `page_layouts` inside a new deck/layout template route. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/template-designer.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/template-designer.md index d0f0c2e6..070eea6a 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/template-designer.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/template-designer.md @@ -58,14 +58,14 @@ Use `summary.md` only for orientation. Open screenshots or the original PPTX onl Every page remains a complete standalone SVG preview. -**Hard rule — mirror graph reachability**: The current structured template -compiler materializes only Master/Layout identities referenced by emitted SVG -prototypes. Before accepting `mirror`, verify that every source Layout has a -non-empty `usedBySlides` set and that every source Master owns at least one such -Layout. If the source package contains an unused Layout or an otherwise -unreachable Master, stop and report that full-graph mirror is not representable -by the current template roster. Never silently drop it, merge it, or invent a -carrier page. +**Hard rule — complete mirror graph**: Restore every supported source Layout, +including Layouts unused by source Slides. Emit one complete source-page +prototype per source Slide and one definition-only +`layout_.svg` prototype for each otherwise unrepresented Layout. +The definition prototype carries the exact parent Master identity, Layout +identity, fixed atoms, and placeholder contract but is not a generated page. +This also retains a source Master that is reachable only through unused Layouts. +Never silently drop or merge an identity, and never invent a carrier page. **Hard rule — no duplicate authored Layout contracts**: In `standard` / `fidelity`, distinct output Layout keys must differ in fixed Layout atoms or slot topology/type/index/bounds/binding. Topic, sample wording, or Slide-local content alone never justifies another authored key. Mirror keeps source Layout identities even when two source contracts are visibly equivalent. @@ -129,12 +129,12 @@ Extension page types beyond the canonical four (transition / appendix / disclaim When the brief sets `Replication mode: mirror`, restore the imported template rather than designing a new one: - Restoration source: lossless `svg/master_*.svg`, `svg/layout_*.svg`, `svg/slide_NN.svg`, `svg-flat/slide_NN.svg`, `svg/inheritance.json`, and `native_structure.json`. Use matching lightweight projections only to inspect the result without loading opaque payload into model context. -- Precondition: every source Layout is referenced by at least one source slide, and every source Master is reachable through those referenced Layouts. Otherwise report that full-graph mirror is currently unsupported and stop before writing output. -- Output: `/templates/_.svg` in both scopes. `` is the zero-padded source slide index (3 digits) and `` is derived from `manifest.json` `pageTypeCandidates` — `cover` / `toc` / `chapter` / `content` / `ending`. When the page-type heuristic is ambiguous, fall back to `content`. Preserve source slide order via the numeric prefix. +- Precondition: the import evidence identifies every source Master/Layout, parent relationship, picker name, placeholder contract, and fixed visual layer. Stop only when required facts or supported geometry are missing; unused identities are not a stop condition. +- Output: `/templates/_.svg` for every source slide, plus `layout_.svg` for every source Layout unused by all source slides. `` is the zero-padded source slide index (3 digits) and `` is derived from `manifest.json` `pageTypeCandidates` — `cover` / `toc` / `chapter` / `content` / `ending`. When the page-type heuristic is ambiguous, fall back to `content`. Preserve source slide order via the numeric prefix; definition-only files are not generated pages. - Required restoration: preserve source Master/Layout keys and picker names, Layout-to-Master parentage, slide assignments, placeholder type/index/bounds, supported native-object metadata, geometry, decoration, sprite-sheet wrappers, original example text, chart previews, fonts, effects, and paint order whenever the importer represents them. - Allowed normalization: add or normalize explicit root declarations and asset paths, and recursively expand fixed Master/Layout group wrappers into direct atoms. The mapping must remain one-to-one at the ownership level and must not change paint order or appearance. - Forbidden: commonality extraction, semantic synthesis, merging, splitting, promotion, demotion, renaming, re-parenting, decorative simplification, placeholder invention, or replacement of supported source-native metadata / SVG fallback with a model-authored approximation. -- `design_spec.md` §V Page Roster lists every emitted file, and `Source Restoration Map` records the preserved source Master/Layout assignment. +- `design_spec.md` §V Page Roster lists every emitted file and marks definition-only prototypes explicitly. `Source Restoration Map` records each source-slide assignment plus every unused Layout definition and its parent Master. **Mirror consumption boundary**: `mirror` applies only while creating the template package from the source deck. Once created, the package is consumed as an ordinary deck / layout template roster: downstream generation may select, repeat, skip, reorder, or adapt pages according to the new content. The `replication_mode: mirror` field must not force the generated deck to preserve the source page count, source order, or one-output-slide-per-template-slide mapping. @@ -492,8 +492,7 @@ templates/ │ ├── anthropic/ # Anthropic brand identity (logo + colors + typography) │ └── google/ # Google brand identity ├── layouts/ -│ ├── academic_defense/ # Academic-defense structure (no identity) -│ └── pixel_retro/ # Pixel retro / cyberpunk structure (no identity) +│ └── presentation_core/ # General structure system (no identity) └── decks/ ├── / # Example banking deck └── / # Example engineering deck diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/README.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/README.md index 2690723d..f8bba05d 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/README.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/README.md @@ -97,7 +97,7 @@ the evidence source for mirror restoration; the projection is inspection-only. The exporter never reads the import workspace or the projection. A projected view is not a final template or release export source. -`template_preview_pptx.py` reads a template workspace, exports every `templates/*.svg` prototype as one structured review slide, and verifies the resulting Master/Layout package. This is an on-demand review action: its default output is `exports/_template_preview.pptx`, and that directory need not exist before the command runs. It refuses an existing output unless an intentional re-export passes `--force`. `--visual-only` is an explicit migration aid for legacy SVG rosters: it creates a slide-local visual review deck without validating or claiming a reusable Master/Layout contract. New structured templates use the default mode when a review deck is requested. +`template_preview_pptx.py` reads a template workspace, exports every `templates/*.svg` prototype as one structured review slide, and verifies the resulting Master/Layout package. This is an on-demand review action: its default output is `exports/_template_preview.pptx`, and that directory need not exist before the command runs. It refuses an existing output unless an intentional re-export passes `--force`. `--visual-only` is an explicit migration aid for legacy SVG rosters: it creates a slide-local visual review deck without validating or claiming a reusable Master/Layout contract. This diagnostic path does not require a project `spec_lock.md`; it may retain generic theme/text defaults inside its clean one-Master/one-Layout shell. New structured templates use the default mode when a review deck is requested. Template fill (direct PPTX, no SVG conversion): @@ -148,13 +148,13 @@ python3 scripts/svg_to_pptx.py For SVG-authoring routes, `svg_output/` is the complete visible page-design source: every exported text, image, shape, background, and template-derived layout element is present in the page SVG or explicitly referenced by it. Export may translate represented content into Master/Layout/Slide parts or native objects, but it does not retrieve missing visible content from templates or planning files. Speaker notes, animation, narration, transitions, `template-fill-pptx`, and `native-enhance-pptx` remain separately owned capabilities. -Native `svg_to_pptx.py` release export uses the project's `structured` lock. Every project supplies a complete Master roster and page-to-Master/Layout mapping before SVG generation. Every SVG root repeats that identity; fixed Master/Layout visuals are direct atomic children, and reusable slots are top-level groups with positive design-zone bounds plus one compatible carrier. Composite `object` regions use explicit proxy binding, and zero-slot Layouts are valid. +Native `svg_to_pptx.py` release export reads the project's explicit structure mode. Free-design and brand-only projects use `flat`, omit Master/Layout mappings and SVG structure metadata, keep every represented object Slide-local, and materialize one clean project-owned Master plus one Blank Layout from the current color/typography lock. Stock content placeholders and unused built-in Layouts are removed; only the standard date/footer/slide-number capability hooks remain. Deck/layout template projects use `structured`: each project supplies unique Master/Layout definitions and one Layout assignment per generated page before SVG generation, and every SVG root repeats its assigned identity. A template-backed definition may remain unused and still register without a published carrier slide. Fixed Master/Layout visuals are direct atomic children; reusable slots are top-level groups with positive design-zone bounds plus one compatible carrier. Composite `object` regions use explicit proxy binding, and zero-slot Layouts are valid. -The exporter compiles only this declared structure, maps locked typography/colors into PowerPoint defaults, creates the named Master/Layout parts, and reads the package back before publication. It never clusters pages, promotes repeated chrome heuristically, or invents placeholders. Use `--pptx-structure flat` only for diagnostics. +Structured template export compiles only the declared structure, maps locked typography/colors into PowerPoint defaults, creates the named Master/Layout parts, and reads the package back before publication. It never clusters pages, promotes repeated chrome heuristically, or invents placeholders. Flat export is the normal free-design/brand-only route: it creates only the clean project-owned shell and performs no promotion or deduplication of Slide content. -Template `page_layouts` records input provenance. Strict preserves its Master/Layout/slot contract; adaptive retains its Master and may use a new Layout key only when fixed Layout atoms or slot topology/bounds change. `standard` / `fidelity` author new SVGs and a new Master/Layout/slot contract. `mirror` restores the source identities and parentage without semantic synthesis, while mechanically expanding fixed-layer group wrappers into the direct atoms required by the structured contract. +Template `page_layouts` records authoring-input provenance, `pptx_masters` / `pptx_layouts` own unique reusable definitions, and `page_pptx_layouts` owns page assignment. Strict preserves its Master/Layout/slot contract; adaptive retains its Master and may use a new Layout key only when fixed Layout atoms or slot topology/bounds change. `standard` / `fidelity` author new SVGs and a new Master/Layout/slot contract. `mirror` restores the complete source identity graph—including unused Layout definitions—without semantic synthesis, while mechanically expanding fixed-layer group wrappers into the direct atoms required by the structured contract. -Legacy `baseline`, `template`, `preserve`, `layout_strategy`, `data-pptx-layout-kind`, `distilled`/`utility`, direct atomic placeholders, and missing root Master identity must run [`restore-pptx-structure`](../workflows/restore-pptx-structure.md) before release export. +Legacy structured/template contracts using `baseline`, `template`, `preserve`, `layout_strategy`, `data-pptx-layout-kind`, `distilled`/`utility`, direct atomic placeholders, or incomplete root Master identity must run [`restore-pptx-structure`](../workflows/restore-pptx-structure.md) before release export. Explicit flat free-design/brand-only projects intentionally omit root Master identity. `pptx_to_svg.py` annotates verified text-grid tables and conservative chart data with `data-pptx-native` metadata. Table import covers exact physical row/grid topology, canonical rectangular merges, safe solid/no-fill per-side borders, plain multi-paragraph cells, and a closed run-rich paragraph schema. Each rich run requires `text` and may use only `bold`, `italic`, `underline`, `strike`, `color`, `font_size`, one `font_family`, `lang`, and `alt_lang`. A merge must use the exact `rowSpan` / `gridSpan` / `hMerge` / `vMerge` physical topology with empty merge slaves. Presentation-only source run XML normalizes, while relationship-bearing text, extensions, line breaks, fields, tabs, bullets, broken text topology, unsafe border XML, non-solid fills, and other merge encodings remain fallback-only. For table style `{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}`, the normalized SVG fallback resolves `wholeTbl`, `firstRow`, horizontal banding, theme colors/fonts, and direct cell/run overrides; other built-in/custom style families are not implied. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/svg-pipeline.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/svg-pipeline.md index 2e16210a..1fdd9804 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/svg-pipeline.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/svg-pipeline.md @@ -66,8 +66,8 @@ Convert project SVGs into PPTX. ```bash python3 scripts/svg_to_pptx.py python3 scripts/svg_to_pptx.py --native-objects -python3 scripts/svg_to_pptx.py --pptx-structure structured # current release structure -python3 scripts/svg_to_pptx.py --pptx-structure flat # structure diagnostic +python3 scripts/svg_to_pptx.py --pptx-structure structured # deck/layout template override +python3 scripts/svg_to_pptx.py --pptx-structure flat # free-design/brand-only override # Template-import visual round-trip diagnostic only: python3 scripts/svg_to_pptx.py -s svg-flat # Post-processed-source comparison diagnostic only (never a release export): @@ -101,16 +101,16 @@ Behavior: inputs and package-level processing. - For PPTX template-import workspaces, use `-s svg-flat` when you need a visual round-trip check. The layered `svg/` tree is the machine-readable template source and intentionally does not inline inherited master / layout decoration into each slide. - Native mode is strict about unsupported visual SVG elements: if a visual element cannot be represented or safely preserved, export fails with the SVG file, element tag, and position instead of silently dropping content. -- Omitting `--pptx-structure` reads `spec_lock.md`; release export requires `mode: structured`. The lock must include a complete `pptx_masters` roster and one `pptx_layouts` row per page. `flat` is diagnostic-only. -- Every page root repeats Master/Layout keys and picker names. Master/Layout fixed visuals are direct atomic children; layer `` elements are invalid. -- Each normal slot is a direct root `` with semantic type, positive design-zone bounds, and exactly one compatible carrier. Composite `object` slots use explicit proxy binding; zero-slot Layouts are valid. -- Structured export maps locked typography/colors into PowerPoint Master/Layout/theme defaults, creates one reusable Layout per declared key, and reopens the package to verify the full Presentation → Master → Layout → Slide graph, fixed-object order, placeholder identities/bounds, carrier bindings, hidden proxies, and zero-slot Layouts. +- Omitting `--pptx-structure` reads `spec_lock.md`. Free-design and brand-only releases declare `mode: flat`, omit Master/Layout mappings and SVG structure metadata, and materialize one clean project-owned Master plus one Blank Layout from the current lock. Deck/layout template releases declare `mode: structured` with complete unique `pptx_masters` / `pptx_layouts` rosters and one `page_pptx_layouts` assignment per page. A template-backed Layout definition may remain unused by pages and still register in the final package. +- On structured template routes, every page root repeats Master/Layout keys and picker names. Master/Layout fixed visuals are direct atomic children; layer `` elements are invalid. +- On structured template routes, each normal slot is a direct root `` with semantic type, positive design-zone bounds, and exactly one compatible carrier. Composite `object` slots use explicit proxy binding; zero-slot Layouts are valid. Flat pages keep all SVG objects Slide-local. +- Flat export maps locked typography/colors into a clean project-owned theme/Master, removes stock content placeholders and unused built-in Layouts, retains only the standard date/footer/slide-number capability hooks, and keeps one Blank Layout without promoting Slide content. Structured export additionally creates one reusable Layout per declared key and reopens the package to verify the full Presentation → Master → Layout → Slide graph, fixed-object order, placeholder identities/bounds, carrier bindings, hidden proxies, and zero-slot Layouts. - Template `page_layouts` remains input provenance. Strict preserves the prototype contract; adaptive retains its Master and may use a new Layout identity only when fixed Layout atoms or slot topology/bounds change. -- Legacy `baseline`, `template`, `preserve`, `layout_strategy`, `data-pptx-layout-kind`, `distilled`/`utility`, direct atomic placeholders, and missing Master identity are rejected with a pointer to [`restore-pptx-structure`](../../workflows/restore-pptx-structure.md). Export never migrates or infers them. +- Legacy structured/template contracts using `baseline`, `template`, `preserve`, `layout_strategy`, `data-pptx-layout-kind`, `distilled`/`utility`, direct atomic placeholders, or incomplete Master identity are rejected with a pointer to [`restore-pptx-structure`](../../workflows/restore-pptx-structure.md). Explicit flat free-design/brand-only projects intentionally omit Master identity. - Native output uses content-hash media filenames, so identical images are reused and different images cannot overwrite each other by sharing a basename. - `[Content_Types].xml` is generated from the actual media extensions written into the PPTX. Unknown media extensions fail unless Python's `mimetypes` can identify them. - Native export writes to a temporary file first and publishes the requested PPTX only after conversion succeeds. A failed conversion does not replace the main output file. -- Before publishing structured-baseline or template-mode native output, export reopens the temporary PPTX and validates the Slide → Layout → Master graph and registrations, Layout identity, placeholder identity, reusable bounds, and prompt/level-one sizes. A mismatch aborts publication; legacy baseline, preserve, and flat skip this gate. +- Before publishing structured template output, export reopens the temporary PPTX and validates the Slide → Layout → Master graph and registrations, Layout identity, placeholder identity, reusable bounds, and prompt/level-one sizes. A mismatch aborts publication. Flat release instead validates its single referenced Master/Layout shell and exact date/footer/slide-number hook roster before packaging. - SVG clip paths are still restricted for authored SVGs, but nested crop wrappers generated by PPTX import are mapped back to native picture crop / geometry when possible. - Speaker notes are embedded automatically unless `--no-notes` is used - Recorded narration is opt-in: diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/image_backends/backend_openai.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/image_backends/backend_openai.py index e0616ad6..aa6918fb 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/image_backends/backend_openai.py +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/image_backends/backend_openai.py @@ -17,6 +17,11 @@ Configuration keys: OPENAI_BACKGROUND (optional) auto or opaque for gpt-image-2 OPENAI_MODERATION (optional) auto or low for GPT image models +Image editing (image-to-image): + When image_gen.py passes reference_image= (single-image CLI only, + via --reference-image), this backend calls /v1/images/edits with the source + image + the prompt as an edit instruction, instead of /v1/images/generations. + Dependencies: pip install requests Pillow """ @@ -38,6 +43,7 @@ if __name__ == "__main__": raise SystemExit(0 if any(arg in {"-h", "--help", "help"} for arg in sys.argv[1:]) else 1) import base64 +import mimetypes import os import time import threading @@ -171,6 +177,10 @@ GPT_IMAGE_BACKGROUNDS = {"auto", "opaque", "transparent"} GPT_IMAGE_MODERATION_VALUES = {"auto", "low"} DEFAULT_BASE_URL = "https://api.openai.com/v1" +# Signals to image_gen.py that this backend can accept a reference_image +# (image-to-image edit via /v1/images/edits). Other backends omit this marker. +SUPPORTS_REFERENCE_IMAGE = True + def _field(value, name: str): """Read a response field from either an SDK object or a dict.""" @@ -312,6 +322,16 @@ def _image_generations_url(base_url: str | None) -> str: return f"{base}/images/generations" +def _image_edits_url(base_url: str | None) -> str: + base = (base_url or DEFAULT_BASE_URL).rstrip("/") + if base.endswith("/images/edits"): + return base + if base.endswith("/images/generations"): + # Swap the sibling endpoint rather than appending to a full URL. + return base[: -len("/generations")] + "/edits" + return f"{base}/images/edits" + + def _read_size_preset() -> str | None: """Read the optional size mapping preset for OpenAI-compatible providers.""" return _read_env_choice("OPENAI_SIZE_PRESET", OPENAI_SIZE_PRESETS) @@ -363,6 +383,32 @@ def _post_image_generation(api_key: str, base_url: str | None, request: dict) -> raise RuntimeError("OpenAI image generation returned invalid JSON.") from exc +def _post_image_edit(api_key: str, base_url: str | None, + data: dict, image_path: str) -> dict: + headers = {"Authorization": f"Bearer {api_key}"} + # GPT Image models take the image list field 'image[]'; dall-e-2 and other + # OpenAI-compatible edit models use the singular 'image'. + model = str(data.get("model", "")) + field = "image[]" if _is_gpt_image_model(model) else "image" + mime_type = mimetypes.guess_type(image_path)[0] or "application/octet-stream" + # Let requests build the multipart/form-data body (and its Content-Type + # boundary) from files=; do not set Content-Type by hand. + with open(image_path, "rb") as image_file: + response = requests.post( + _image_edits_url(base_url), + headers=headers, + data=data, + files=[(field, (Path(image_path).name, image_file, mime_type))], + timeout=300, + ) + if not response.ok: + raise http_error(response, "OpenAI image edit") + try: + return response.json() + except ValueError as exc: + raise RuntimeError("OpenAI image edit returned invalid JSON.") from exc + + # ╔══════════════════════════════════════════════════════════════════╗ # ║ Image Generation ║ # ╚══════════════════════════════════════════════════════════════════╝ @@ -465,6 +511,103 @@ def _generate_image(api_key: str, prompt: str, raise RuntimeError("No image was generated. The server may have refused the request.") +def _edit_image(api_key: str, prompt: str, reference_image: str, + aspect_ratio: str = "1:1", image_size: str = "1K", + output_dir: str = None, filename: str = None, + model: str = DEFAULT_MODEL, base_url: str = None) -> str: + """ + Image-to-image edit via the OpenAI-compatible /v1/images/edits endpoint. + + Sends the reference image plus the prompt (used as the edit instruction). + Mirrors _generate_image's size/quality/format handling but posts + multipart/form-data instead of JSON. + + Returns: + Path of the saved image file + """ + size_preset = _read_size_preset() + size = _select_size(model, aspect_ratio, image_size, size_preset) + quality = None if _is_dall_e_2(model) else _read_quality(image_size) + output_ext = ".png" + request = { + "prompt": prompt, + "model": model, + "size": size, + "n": 1, + } + if quality is not None: + request["quality"] = quality + if _is_gpt_image_model(model): + gpt_options, output_ext = _gpt_image_options(model) + request.update(gpt_options) + _apply_response_format(request, model) + + mode_label = f"Proxy: {base_url}" if base_url else "OpenAI API" + print(f"[OpenAI - {mode_label}]") + print(f" Mode: edit (image-to-image)") + print(f" Model: {model}") + print(f" Reference: {reference_image}") + print(f" Prompt: {prompt[:120]}{'...' if len(prompt) > 120 else ''}") + print(f" Size: {size} (from aspect_ratio={aspect_ratio})") + if size_preset and size_preset != "auto": + print(f" Size Preset: {size_preset}") + if quality is not None: + print(f" Quality: {quality} (from image_size={image_size})") + else: + print(" Quality: omitted") + if request.get("response_format"): + print(f" Response: {request['response_format']}") + elif _read_response_format() == "omit": + print(" Response: omitted") + if request.get("output_format"): + print(f" Format: {request['output_format']}") + if request.get("output_compression") is not None: + print(f" Compression: {request['output_compression']}") + if request.get("background"): + print(f" Background: {request['background']}") + if request.get("moderation"): + print(f" Moderation: {request['moderation']}") + print() + + start_time = time.time() + print(f" [..] Editing...", end="", flush=True) + + heartbeat_stop = threading.Event() + + def _heartbeat(): + while not heartbeat_stop.is_set(): + heartbeat_stop.wait(5) + if not heartbeat_stop.is_set(): + elapsed = time.time() - start_time + print(f" {elapsed:.0f}s...", end="", flush=True) + + hb_thread = threading.Thread(target=_heartbeat, daemon=True) + hb_thread.start() + + try: + resp = _post_image_edit(api_key, base_url, request, reference_image) + finally: + heartbeat_stop.set() + hb_thread.join(timeout=1) + + elapsed = time.time() - start_time + print(f"\n [DONE] Image edited ({elapsed:.1f}s)") + + data = _field(resp, "data") if resp is not None else None + if data: + path = resolve_output_path(prompt, output_dir, filename, output_ext) + first_image = data[0] + b64_json = _field(first_image, "b64_json") + image_url = _field(first_image, "url") + if b64_json: + image_data = base64.b64decode(b64_json) + return save_image_bytes(image_data, path) + if image_url: + return download_image(image_url, path) + + raise RuntimeError("No image was returned. The server may have refused the edit request.") + + # ╔══════════════════════════════════════════════════════════════════╗ # ║ Public Entry Point ║ # ╚══════════════════════════════════════════════════════════════════╝ @@ -472,9 +615,10 @@ def _generate_image(api_key: str, prompt: str, def generate(prompt: str, aspect_ratio: str = "1:1", image_size: str = "1K", output_dir: str = None, filename: str = None, - model: str = None, max_retries: int = MAX_RETRIES) -> str: + model: str = None, max_retries: int = MAX_RETRIES, + reference_image: str = None) -> str: """ - OpenAI-compatible image generation with automatic retry. + OpenAI-compatible image generation (or image-to-image edit) with retry. Reads credentials from the current process environment or a `.env` file: OPENAI_API_KEY @@ -482,13 +626,16 @@ def generate(prompt: str, OPENAI_MODEL (optional override) Args: - prompt: Prompt text + prompt: Prompt text (edit instruction when reference_image is set) aspect_ratio: Aspect ratio, mapped to OpenAI size image_size: Image size, mapped to OpenAI quality output_dir: Output directory filename: Output filename (without extension) model: Model name (default: gpt-image-2) max_retries: Maximum number of retries + reference_image: Optional source image path. When set, the request + goes to /v1/images/edits (image-to-image) instead of + /v1/images/generations. Returns: Path of the saved image file @@ -516,6 +663,10 @@ def generate(prompt: str, last_error = None for attempt in range(max_retries + 1): try: + if reference_image is not None: + return _edit_image(api_key, prompt, reference_image, + aspect_ratio, image_size, output_dir, + filename, model, base_url) return _generate_image(api_key, prompt, aspect_ratio, image_size, output_dir, filename, model, base_url) diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/image_gen.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/image_gen.py index 1c26b716..3645cbf8 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/image_gen.py +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/image_gen.py @@ -39,6 +39,7 @@ Supported keys: Usage: python3 image_gen.py "prompt" --aspect_ratio 16:9 --image_size 1K -o images/ + python3 image_gen.py "edit instruction" --reference-image src.png -o images/ python3 image_gen.py --manifest project/images/image_prompts.json -o project/images/ python3 image_gen.py --list-backends """ @@ -690,8 +691,11 @@ def main() -> None: description="Generate images using AI image model providers." ) parser.add_argument( - "prompt", nargs="?", default="a beautiful landscape", - help="The text prompt for image generation." + "prompt", nargs="?", default=None, + help=( + "The text prompt for image generation. With --reference-image, " + "this is the edit instruction (required in that mode)." + ) ) parser.add_argument( "--aspect_ratio", default="1:1", choices=ALL_ASPECT_RATIOS, @@ -743,9 +747,42 @@ def main() -> None: "next to the manifest, then exit. No backend / network needed." ), ) + parser.add_argument( + "--reference-image", dest="reference_image", default=None, metavar="PATH", + help=( + "Source image for image-to-image editing (single-image mode only). " + "When set, the prompt is used as the edit instruction. Only backends " + "that support editing accept this (currently: openai). Not valid with " + "--manifest / --render-md / --list-backends." + ), + ) args = parser.parse_args() + if args.reference_image is not None: + # Reference editing is a single-image-only enhancement; keep it out of + # the manifest / sidecar / list surfaces entirely. + conflicting = [ + name for name, val in ( + ("--manifest", args.manifest), + ("--render-md", args.render_md), + ("--list-backends", args.list_backends), + ) if val + ] + if conflicting: + parser.error( + "--reference-image is single-image mode only and cannot be " + f"combined with {', '.join(conflicting)}." + ) + if not args.prompt or not args.prompt.strip(): + parser.error( + "--reference-image requires a prompt to use as the edit instruction." + ) + if not os.path.isfile(args.reference_image): + parser.error( + f"--reference-image file not found: {args.reference_image}" + ) + if args.list_backends: _print_backend_list() return @@ -806,15 +843,30 @@ def main() -> None: print(f"Rendered Markdown sidecar: {md_path}") sys.exit(1 if failed else 0) + # Single-image mode. Backfill the historical default prompt only here, so + # plain generation is byte-for-byte unchanged while edit mode still requires + # an explicit instruction (enforced above). + prompt = args.prompt if args.prompt is not None else "a beautiful landscape" + + gen_kwargs = { + "prompt": prompt, + "aspect_ratio": args.aspect_ratio, + "image_size": args.image_size, + "output_dir": args.output, + "filename": args.filename, + "model": args.model, + } + if args.reference_image is not None: + if not getattr(backend, "SUPPORTS_REFERENCE_IMAGE", False): + print( + f"Error: backend '{backend_name}' does not support image editing " + "(--reference-image). Use a backend that does (currently: openai)." + ) + sys.exit(1) + gen_kwargs["reference_image"] = args.reference_image + try: - backend.generate( - prompt=args.prompt, - aspect_ratio=args.aspect_ratio, - image_size=args.image_size, - output_dir=args.output, - filename=args.filename, - model=args.model, - ) + backend.generate(**gen_kwargs) except (ValueError, FileNotFoundError) as e: print(f"Error: {e}") sys.exit(1) diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/register_template.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/register_template.py index 98c3caa6..103657cc 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/register_template.py +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/register_template.py @@ -43,8 +43,10 @@ import re import sys from collections import OrderedDict from pathlib import Path +from xml.etree import ElementTree as ET from console_encoding import configure_utf8_stdio +from config import CANVAS_FORMATS try: import yaml # type: ignore @@ -80,6 +82,24 @@ KIND_CONFIG = { }, } +_BRAND_REQUIRED_SECTIONS = ( + "Brand Overview", + "Color Scheme", + "Typography", + "Logo", + "Voice & Tone", + "Icon Style", +) +_BRAND_FORBIDDEN_SECTIONS = ( + "Page Roster", + "Signature Design Elements", +) +_BRAND_PROVENANCE_VALUES = {"fact", "approx", "user"} +_BRAND_ASSET_REF_RE = re.compile( + r"`((?:\.\./)+(?:images|icons)/[^`]+)`" +) +_HEX_COLOR_RE = re.compile(r"#[0-9A-Fa-f]{6}") + # --------------------------------------------------------------------------- # design_spec.md parsing @@ -200,6 +220,264 @@ def _derive_page_types(pages: list[str]) -> list[str]: return types +def _numbered_section(body: str, title: str) -> str | None: + match = re.search( + rf"^##\s+[IVX]+\.\s+{re.escape(title)}\s*$.*?(?=^##\s+|\Z)", + body, + re.MULTILINE | re.DOTALL, + ) + return match.group(0) if match else None + + +def _validate_brand_spec( + template_id: str, + template_root: Path, + template_dir: Path, + frontmatter: dict, + body: str, + pages: list[str], +) -> None: + """Reject brand workspaces that cannot be locked as portable identity truth. + + Args: + template_id: Directory name used as the registry key. + template_root: Brand workspace root containing assets and templates. + template_dir: Directory containing ``design_spec.md`` and any page SVGs. + frontmatter: Parsed design-spec frontmatter. + body: Markdown content after the frontmatter block. + pages: SVG page stems discovered beside the design spec. + """ + errors: list[str] = [] + + declared_id = str(frontmatter.get("brand_id") or "").strip() + if declared_id != template_id: + errors.append( + f"frontmatter brand_id must match directory {template_id!r}, " + f"got {declared_id!r}" + ) + + declared_kind = str(frontmatter.get("kind") or "").strip() + if declared_kind != "brand": + errors.append( + "frontmatter kind must be 'brand', " + f"got {declared_kind!r}" + ) + + if pages: + errors.append( + "brand workspaces must not contain page SVGs under templates/: " + + ", ".join(f"{page}.svg" for page in pages) + ) + + for title in _BRAND_REQUIRED_SECTIONS: + if _numbered_section(body, title) is None: + errors.append(f"missing required section: {title}") + + for title in _BRAND_FORBIDDEN_SECTIONS: + if re.search( + rf"^##\s+(?:[IVX]+\.\s+)?{re.escape(title)}\s*$", + body, + re.MULTILINE, + ): + errors.append(f"brand scope must not declare section: {title}") + + declared_primary = str(frontmatter.get("primary_color") or "").strip() + if _HEX_COLOR_RE.fullmatch(declared_primary) is None: + errors.append( + "frontmatter primary_color must use #RRGGBB, " + f"got {declared_primary!r}" + ) + + color_section = _numbered_section(body, "Color Scheme") or "" + primary_rows: list[str] = [] + for line in color_section.splitlines(): + if not line.lstrip().startswith("|"): + continue + cells = [cell.strip() for cell in line.strip().strip("|").split("|")] + if len(cells) < 3: + continue + role = cells[0].strip("` ") + raw_color = cells[1].strip("` ") + if role.lower() == "role" or re.fullmatch(r":?-+:?", role): + continue + if _HEX_COLOR_RE.fullmatch(raw_color) is None: + errors.append( + f"color row {role!r} must use #RRGGBB, " + f"got {raw_color!r}" + ) + continue + if role.lower() == "primary": + primary_rows.append(raw_color.upper()) + provenance = cells[2].strip("` ").lower() + if provenance not in _BRAND_PROVENANCE_VALUES: + errors.append( + f"color {raw_color} must declare provenance as " + "fact, approx, or user" + ) + + if not primary_rows: + errors.append("Color Scheme must declare one primary color row") + elif len(primary_rows) > 1: + errors.append("Color Scheme must declare only one primary color row") + elif ( + _HEX_COLOR_RE.fullmatch(declared_primary) + and primary_rows[0] != declared_primary.upper() + ): + errors.append( + "Color Scheme primary must match frontmatter primary_color: " + f"{primary_rows[0]} != {declared_primary.upper()}" + ) + + root = template_root.resolve() + for raw_ref in sorted(set(_BRAND_ASSET_REF_RE.findall(body))): + asset = (template_dir / raw_ref).resolve() + try: + asset.relative_to(root) + except ValueError: + errors.append(f"asset reference escapes brand workspace: {raw_ref}") + continue + if not asset.is_file(): + errors.append(f"referenced brand asset does not exist: {raw_ref}") + + if errors: + details = "\n".join(f" - {error}" for error in errors) + raise SpecParseError(f"invalid brand specification:\n{details}") + + +def _validate_svg_template_spec( + kind: str, + template_id: str, + template_dir: Path, + frontmatter: dict, + pages: list[str], +) -> None: + """Reject Layout/Deck workspaces whose registry facts drift from SVGs.""" + errors: list[str] = [] + id_key = KIND_CONFIG[kind]["id_key"] + declared_id = str(frontmatter.get(id_key) or "").strip() + if declared_id != template_id: + errors.append( + f"frontmatter {id_key} must match directory {template_id!r}, " + f"got {declared_id!r}" + ) + declared_kind = str(frontmatter.get("kind") or "").strip() + if declared_kind != kind: + errors.append( + f"frontmatter kind must be {kind!r}, got {declared_kind!r}" + ) + if not str(frontmatter.get("summary") or "").strip(): + errors.append("frontmatter summary must be non-empty") + if not pages: + errors.append(f"{kind} workspace must contain at least one template SVG") + + raw_page_count = frontmatter.get("page_count") + if isinstance(raw_page_count, bool) or not isinstance(raw_page_count, int): + errors.append("frontmatter page_count must be an integer") + elif raw_page_count != len(pages): + errors.append( + f"frontmatter page_count is {raw_page_count}, but templates/ " + f"contains {len(pages)} SVG files" + ) + + canvas_format = str(frontmatter.get("canvas_format") or "").strip() + canvas = CANVAS_FORMATS.get(canvas_format) + if canvas is None: + errors.append( + "frontmatter canvas_format must be one of: " + + ", ".join(sorted(CANVAS_FORMATS)) + ) + else: + expected_canvas_fields = { + "canvas_width": canvas["width"], + "canvas_height": canvas["height"], + "canvas_viewbox": canvas["viewbox"], + } + for field, expected in expected_canvas_fields.items(): + actual = frontmatter.get(field) + if str(actual) != str(expected): + errors.append( + f"frontmatter {field} must be {expected!r} for " + f"{canvas_format}, got {actual!r}" + ) + + if frontmatter.get("native_structure_mode") != "structured": + errors.append( + "frontmatter native_structure_mode must be 'structured'" + ) + if frontmatter.get("replication_mode") not in { + "standard", + "fidelity", + "mirror", + }: + errors.append( + "frontmatter replication_mode must be standard, fidelity, or mirror" + ) + + if kind == "layout": + raw_page_types = frontmatter.get("page_types") + expected_page_types = _derive_page_types(pages) + if not isinstance(raw_page_types, list) or not all( + isinstance(item, str) and item.strip() + for item in raw_page_types + ): + errors.append("frontmatter page_types must be a non-empty string list") + elif raw_page_types != expected_page_types: + errors.append( + "frontmatter page_types must exactly match the SVG filename " + f"roster: expected {expected_page_types!r}, got {raw_page_types!r}" + ) + else: + primary_color = str(frontmatter.get("primary_color") or "").strip() + if _HEX_COLOR_RE.fullmatch(primary_color) is None: + errors.append( + "frontmatter primary_color must use #RRGGBB, " + f"got {primary_color!r}" + ) + + svg_paths = [template_dir / f"{page}.svg" for page in pages] + if canvas is not None: + expected_viewbox = str(canvas["viewbox"]) + for svg_path in svg_paths: + try: + root = ET.parse(svg_path).getroot() + except (OSError, ET.ParseError) as exc: + errors.append(f"{svg_path.name} is not valid SVG XML: {exc}") + continue + actual_canvas = ( + root.get("width"), + root.get("height"), + root.get("viewBox"), + ) + expected_canvas = ( + str(canvas["width"]), + str(canvas["height"]), + expected_viewbox, + ) + if actual_canvas != expected_canvas: + errors.append( + f"{svg_path.name} canvas is {actual_canvas!r}, expected " + f"{expected_canvas!r}" + ) + + if svg_paths: + try: + from svg_to_pptx.pptx_package.template_structure import ( + TemplateStructureError, + parse_template_slides, + ) + except ImportError as exc: + errors.append(f"structured SVG roster is invalid: {exc}") + else: + try: + parse_template_slides(svg_paths) + except TemplateStructureError as exc: + errors.append(f"structured SVG roster is invalid: {exc}") + + if errors: + details = "\n".join(f" - {error}" for error in errors) + raise SpecParseError(f"invalid {kind} specification:\n{details}") + + # --------------------------------------------------------------------------- # Per-kind extraction # --------------------------------------------------------------------------- @@ -233,25 +511,45 @@ def _extract_entry(kind: str, template_id: str, template_dir: Path) -> dict: primary_color = fm.get("primary_color") or _extract_primary_color(body) or "" if kind == "brand": + _validate_brand_spec( + template_id, + template_root, + template_dir, + fm, + body, + pages, + ) entry = OrderedDict( summary=summary, primary_color=str(primary_color), ) elif kind == "layout": - page_types = fm.get("page_types") or _derive_page_types(pages) - if isinstance(page_types, str): - page_types = [t.strip() for t in re.split(r"[,,]", page_types) if t.strip()] + _validate_svg_template_spec( + kind, + template_id, + template_dir, + fm, + pages, + ) + page_types = fm["page_types"] entry = OrderedDict( summary=summary, - canvas_format=str(fm.get("canvas_format", "ppt169")), - page_count=int(fm.get("page_count", len(pages))), + canvas_format=str(fm["canvas_format"]), + page_count=int(fm["page_count"]), page_types=list(page_types), ) elif kind == "deck": + _validate_svg_template_spec( + kind, + template_id, + template_dir, + fm, + pages, + ) entry = OrderedDict( summary=summary, - canvas_format=str(fm.get("canvas_format", "ppt169")), - page_count=int(fm.get("page_count", len(pages))), + canvas_format=str(fm["canvas_format"]), + page_count=int(fm["page_count"]), primary_color=str(primary_color), ) else: diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_editor/annotations.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_editor/annotations.py index 7a02353c..d7e252ef 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_editor/annotations.py +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_editor/annotations.py @@ -19,9 +19,11 @@ from copy import deepcopy from typing import Optional SVG_NS = 'http://www.w3.org/2000/svg' +XLINK_NS = 'http://www.w3.org/1999/xlink' -# Register namespace to avoid ns0: prefix in output +# Register namespaces to avoid generated ns0/ns1 prefixes in saved SVGs. ET.register_namespace('', SVG_NS) +ET.register_namespace('xlink', XLINK_NS) def assign_temp_ids(root: ET.Element) -> None: diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_editor/server.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_editor/server.py index d1d74a74..25cf747c 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_editor/server.py +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_editor/server.py @@ -97,6 +97,7 @@ from svg_to_pptx.geometry_properties import ( # noqa: E402 _ICONS_DIR = _SCRIPTS_DIR.parent.parent / 'templates' / 'icons' _USE_ICON_PATTERN = re.compile(r']*data-icon="[^"]*"[^>]*/>') +_XLINK_HREF = '{http://www.w3.org/1999/xlink}href' # Per-path mtime caches: key = absolute path str, value = (mtime, payload). # Entry is evicted/replaced when the file's mtime changes, so stale data @@ -136,6 +137,24 @@ def _cache_put(cache: dict, lock: threading.Lock, path: str, mtime: float, value cache[path] = (mtime, value) +def _normalize_preview_hrefs(root: ET.Element) -> None: + """Normalize legacy XLink references in the browser-only SVG copy. + + ElementTree otherwise serializes an unregistered/legacy namespace with an + arbitrary prefix. The HTML SVG parser only gives special namespace handling + to ``xlink:href``; an arbitrary prefix can therefore render as an inert + attribute after ``innerHTML`` insertion. SVG 2 ``href`` works for both + images and local ``use`` references and avoids that parser boundary. + """ + for elem in root.iter(): + legacy_href = elem.get(_XLINK_HREF) + if legacy_href is None: + continue + if elem.get('href') is None: + elem.set('href', legacy_href) + elem.attrib.pop(_XLINK_HREF, None) + + # Lock / liveness helpers are shared with confirm_ui via server_common. @@ -648,6 +667,7 @@ def create_app( if '}' in tag: tag = tag.split('}', 1)[1] id_to_tag[eid] = tag + _normalize_preview_hrefs(root) content = ET.tostring(root, encoding='unicode', xml_declaration=False) content, warnings = _inline_icons(content) if not pending_edits: diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_editor/static/app.js b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_editor/static/app.js index 6327536e..6a6647a1 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_editor/static/app.js +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_editor/static/app.js @@ -1730,10 +1730,10 @@ Array.from(el.attributes).forEach(function (attr) { if (attr.name.indexOf("on") === 0) el.removeAttribute(attr.name); // Strip dangerous URI protocols from href/xlink:href - if ((attr.name === "href" || attr.name === "xlink:href") && + if (attr.localName === "href" && (/^\s*javascript\s*:/i.test(attr.value) || /^\s*data\s*:/i.test(attr.value))) { - el.removeAttribute(attr.name); + el.removeAttributeNode(attr); } }); }); diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_quality_checker.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_quality_checker.py index 1e40a183..0ffa79aa 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_quality_checker.py +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_quality_checker.py @@ -190,6 +190,23 @@ except ImportError: _template_prototype_errors = None _validate_template_structure_svg = None +try: + from svg_to_pptx.drawingml.theme_colors import ( + ThemeColorError as _ThemeColorError, + load_theme_color_spec as _load_theme_color_spec, + ) + from svg_to_pptx.drawingml.theme_fonts import ( + ThemeFontError as _ThemeFontError, + load_master_text_style_spec as _load_master_text_style_spec, + load_theme_font_spec as _load_theme_font_spec, + ) +except ImportError: + _ThemeColorError = None + _ThemeFontError = None + _load_theme_color_spec = None + _load_master_text_style_spec = None + _load_theme_font_spec = None + try: from svg_finalize.embed_icons import ( resolve_icon_path as _resolve_icon_path, @@ -216,6 +233,16 @@ except ImportError: HEX_VALUE_RE = re.compile( r"#(?:[0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})" ) + +# Master/Layout preflight validation. Structured deck/layout-template projects +# are checked at authoring time; the exporter remains the final OOXML/package +# authority. Flat projects only receive the negative guard that rejects authored +# structure metadata. Template roster/placeholder checks always run. Current +# bundled templates opt in to complete structure validation through their +# native_structure_mode: structured declaration. Legacy template-mode packages +# fail closed and must run the explicit restoration workflow. +_CHECK_PPTX_STRUCTURED_PROJECT = True + _BARE_HEX_VALUE_RE = re.compile( r"(?:[0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})" ) @@ -267,6 +294,47 @@ _SUPPORTED_FILTER_PRIMITIVES = frozenset({ 'feFuncA', }) _FILTER_EFFECT_PRIMITIVES = frozenset({'feDropShadow', 'feGaussianBlur'}) +_FILTER_PUBLIC_TARGETS = frozenset({'rect', 'circle', 'path', 'text'}) +_CLIP_SHAPE_TAGS = frozenset({'circle', 'ellipse', 'rect', 'path', 'polygon'}) +_DEFINITION_TAGS = frozenset({ + 'clipPath', + 'filter', + 'linearGradient', + 'marker', + 'pattern', + 'radialGradient', +}) +_ALPHA_PROPERTIES = ( + 'opacity', + 'fill-opacity', + 'stroke-opacity', + 'stop-opacity', + 'flood-opacity', +) +_SUPPORTED_INLINE_STYLE_PROPERTIES = frozenset({ + 'cx', 'cy', 'fill', 'fill-opacity', 'filter', 'flood-color', + 'flood-opacity', 'font-family', 'font-size', 'font-style', 'font-weight', + 'height', 'letter-spacing', 'opacity', 'r', 'rx', 'ry', + 'shape-rendering', 'stop-color', 'stop-opacity', 'stroke', + 'stroke-dasharray', 'stroke-linecap', 'stroke-linejoin', 'stroke-opacity', + 'stroke-width', 'text-anchor', 'text-decoration', 'vector-effect', + 'width', 'x', 'y', +}) +_BAKE_REQUIRED_VISUAL_PROPERTIES = frozenset({ + 'backdrop-filter', + 'isolation', + 'mix-blend-mode', +}) +_NUMBER_TOKEN = r'[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?' +_POINT_TOKEN = rf'{_NUMBER_TOKEN}(?:\s*,\s*|\s+){_NUMBER_TOKEN}' +_MARKER_TRIANGLE_PATH_RE = re.compile( + rf'^\s*M\s*{_POINT_TOKEN}(?:\s*L\s*{_POINT_TOKEN}){{2}}\s*Z\s*$', + re.IGNORECASE, +) +_MARKER_DIAMOND_PATH_RE = re.compile( + rf'^\s*M\s*{_POINT_TOKEN}(?:\s*L\s*{_POINT_TOKEN}){{3}}\s*Z\s*$', + re.IGNORECASE, +) def _declared_pptx_structure_mode(project_path: Path) -> str | None: @@ -283,6 +351,39 @@ def _declared_pptx_structure_mode(project_path: Path) -> str | None: return mode_match.group(1).strip().lower() if mode_match else None +def _generated_theme_contract_errors(project_path: Path) -> List[str]: + """Validate the current-project theme contract required by release export.""" + if ( + _ThemeColorError is None + or _ThemeFontError is None + or _load_theme_color_spec is None + or _load_master_text_style_spec is None + or _load_theme_font_spec is None + ): + return [ + "PowerPoint theme contract validation is unavailable because the " + "theme loader modules could not be imported." + ] + try: + theme_font_spec = _load_theme_font_spec(project_path) + _load_master_text_style_spec(project_path) + theme_color_spec = _load_theme_color_spec(project_path) + except (_ThemeFontError, _ThemeColorError) as exc: + return [str(exc)] + + missing: List[str] = [] + if theme_font_spec is None: + missing.append("typography font_family/title_family/body_family") + if theme_color_spec is None: + missing.append("colors") + if not missing: + return [] + return [ + "spec_lock.md generated PowerPoint theme contract is missing: " + + ", ".join(missing) + ] + + def _placeholder_bounds_error(value: str) -> str | None: """Return a concise error for invalid design-zone bounds.""" raw_values = [item for item in re.split(r"[\s,]+", value.strip()) if item] @@ -569,6 +670,32 @@ def _design_spec_is_brand(spec_path: Path) -> bool: return False +def _declared_template_structure_mode(target_path: Path) -> str | None: + """Return a template directory's explicit native structure mode.""" + directory = target_path.parent if target_path.is_file() else target_path + spec_path = directory / 'design_spec.md' + try: + text = spec_path.read_text(encoding='utf-8') + except OSError: + return None + if not text.startswith('---\n'): + return None + end = text.find('\n---\n', 4) + if end == -1: + return None + match = re.search( + r'^native_structure_mode:\s*([A-Za-z0-9_-]+)\s*$', + text[4:end], + re.MULTILINE, + ) + return match.group(1).lower() if match else None + + +def _template_structure_checks_enabled(target_path: Path) -> bool: + """Return whether positive structure checks apply to this template.""" + return _declared_template_structure_mode(target_path) == 'structured' + + def _local_name(elem: ET.Element) -> str: """Return an XML element's namespace-free local tag name.""" tag = elem.tag @@ -577,6 +704,98 @@ def _local_name(elem: ET.Element) -> str: return tag.rsplit('}', 1)[-1] if '}' in tag else tag +def _direct_defs_index( + root: ET.Element, +) -> tuple[Dict[str, ET.Element], set[str]]: + """Return direct ```` children by id plus duplicate ids.""" + definitions: Dict[str, ET.Element] = {} + duplicates: set[str] = set() + for defs_elem in root.iter(): + if _local_name(defs_elem) != 'defs': + continue + for child in defs_elem: + definition_id = (child.get('id') or '').strip() + if not definition_id: + continue + if definition_id in definitions: + duplicates.add(definition_id) + definitions[definition_id] = child + return definitions, duplicates + + +def _element_label(elem: ET.Element) -> str: + """Return a compact element label for validation messages.""" + tag = _local_name(elem) + elem_id = (elem.get('id') or '').strip() + return f'<{tag} id="{elem_id}">' if elem_id else f'<{tag}>' + + +def _finite_unit_interval(raw: str) -> float | None: + """Parse a finite unitless number in the closed interval ``0..1``.""" + if re.fullmatch(_NUMBER_TOKEN, raw.strip()) is None: + return None + try: + value = float(raw) + except ValueError: + return None + if not math.isfinite(value) or not 0.0 <= value <= 1.0: + return None + return value + + +def _normalized_gradient_value(raw: str) -> float | None: + """Parse a normalized gradient coordinate or percentage.""" + value_text = raw.strip() + is_percent = value_text.endswith('%') + if is_percent: + value_text = value_text[:-1].strip() + if re.fullmatch(_NUMBER_TOKEN, value_text) is None: + return None + try: + value = float(value_text) + except ValueError: + return None + if not math.isfinite(value): + return None + value = value / 100.0 if is_percent else value + return value if 0.0 <= value <= 1.0 else None + + +def _marker_polygon_vertex_count(raw: str) -> int | None: + """Return the number of finite polygon vertices, or ``None``.""" + tokens = [token for token in re.split(r'[\s,]+', raw.strip()) if token] + if not tokens or len(tokens) % 2: + return None + try: + values = [float(token) for token in tokens] + except ValueError: + return None + if not all(math.isfinite(value) for value in values): + return None + return len(values) // 2 + + +def _effective_presentation_value( + elem: ET.Element, + name: str, + parent_by_id: Dict[int, ET.Element], +) -> str | None: + """Resolve one inherited presentation property for validation.""" + current: ET.Element | None = elem + while current is not None: + style_values = ( + _parse_inline_style(current.get('style')) + if _parse_inline_style is not None else {} + ) + if name in style_values: + return style_values[name] + direct = current.get(name) + if direct is not None: + return direct + current = parent_by_id.get(id(current)) + return None + + def _parse_viewbox_values(viewbox: str) -> Tuple[float, float, float, float] | None: """Parse a root viewBox into four numeric values.""" parts = re.split(r'[\s,]+', viewbox.strip()) @@ -776,10 +995,17 @@ class SVGQualityChecker: # 2. Check forbidden elements self._check_forbidden_elements(content, root, result) - # 2b. Validate the supported shadow/glow filter interface. + # 2b. Validate the closed authoring-property surface and + # conditional definition interfaces before export. + self._check_authoring_property_contract(root, result) + self._check_definition_contract(root, result) + self._check_marker_contract(root, result) + self._check_clip_path_contract(root, result) + + # 2c. Validate the supported shadow/glow filter interface. self._check_filter_effects(root, result) - # 2c. Reject gradient inheritance and transform semantics. + # 2d. Validate gradient definitions, stops, and coordinates. self._check_gradient_interfaces(root, result) # 3. Check font-size values @@ -814,7 +1040,12 @@ class SVGQualityChecker: self._check_native_object_markers(root, result) # 8d. Validate explicit master/layout/placeholder metadata. - self._check_pptx_structure_metadata(root, svg_path, result) + if ( + _template_structure_checks_enabled(svg_path) + if self.template_mode + else _CHECK_PPTX_STRUCTURED_PROJECT + ): + self._check_pptx_structure_metadata(root, svg_path, result) # 8e. Validate rendering-neutral page/structure compiler hints. self._check_semantic_markers(root, svg_path, result) @@ -928,28 +1159,8 @@ class SVGQualityChecker: # Forbidden elements blocklist - PPT incompatible # ============================================================ - # Clipping / masking - # clipPath is allowed on elements and on pptx_to_svg-generated - # nested crop wrappers. Both map back to - # DrawingML picture geometry in the native converter. - if 'clippath' in local_names: - ids = {elem.get('id') for elem in elems if elem.get('id')} - for elem in elems: - clip_ref = elem.get('clip-path') - if not clip_ref: - continue - tag = _local_name(elem).lower() - is_crop_svg = tag == 'svg' and elem.get('data-pptx-crop') == '1' - if tag != 'image' and not is_crop_svg: - result['errors'].append( - "clip-path is only allowed on elements or " - "pptx_to_svg crop wrappers — for shapes, draw the target " - "shape directly instead of clipping") - match = re.search(r'url\(#([^)]+)\)', clip_ref) - if match and match.group(1) not in ids: - result['errors'].append( - f"clip-path references #{match.group(1)} but no matching " - f" definition found") + # Clipping / masking. The closed image clip-path contract is validated + # separately by _check_clip_path_contract. if 'mask' in local_names: result['errors'].append("Detected forbidden element (PPT does not support SVG masks)") @@ -1000,15 +1211,6 @@ class SVGQualityChecker: else: for error in _validate_local_use_references(root): result['errors'].append(f"Invalid local reference: {error}") - # marker-start / marker-end are conditionally allowed (see shared-standards.md §1.1). - # The converter maps qualifying defs to native DrawingML /. - # We only warn when a marker is used without an obvious definition in the same file. - if re.search(r'\bmarker-(?:start|end)\s*=\s*["\']url\(#([^)]+)\)', content_lower): - if 'marker' not in local_names: - result['errors'].append( - "Detected marker-start/marker-end referencing a marker id, " - "but no element found in the file") - # Text / fonts if 'textpath' in local_names: result['errors'].append("Detected forbidden element (path text is incompatible with PPT)") @@ -1152,81 +1354,382 @@ class SVGQualityChecker: f"{shown}{suffix}. Use a supported named color, rgb()/rgba(), " "hsl()/hsla(), or #RGB/#RGBA/#RRGGBB/#RRGGBBAA." ) - for elem in elems: + + def _check_authoring_property_contract( + self, + root: ET.Element, + result: Dict, + ) -> None: + """Validate inline CSS and alpha values against the authoring surface.""" + issues: set[str] = set() + for elem in root.iter(): + label = _element_label(elem) + style_declarations: list[tuple[str, str]] = [] + for fragment in (elem.get('style') or '').split(';'): + fragment = fragment.strip() + if not fragment: + continue + if ':' not in fragment: + issues.add( + f"{label} has malformed inline style declaration {fragment!r}" + ) + continue + name, value = fragment.split(':', 1) + name = name.strip().lower() + value = value.strip() + if not name or not value: + issues.add( + f"{label} has malformed inline style declaration {fragment!r}" + ) + continue + style_declarations.append((name, value)) + if name in _BAKE_REQUIRED_VISUAL_PROPERTIES: + issues.add( + f"{label} uses Bake-required visual property {name!r}; " + "bake the effect or rebuild it with supported geometry" + ) + elif name not in _SUPPORTED_INLINE_STYLE_PROPERTIES: + issues.add( + f"{label} uses unsupported inline style property {name!r}; " + "native PPTX export would ignore it" + ) + if '!important' in value.lower(): + issues.add( + f"{label} inline style property {name!r} cannot use !important" + ) + + for attr_name in elem.attrib: + local_attr = attr_name.rsplit('}', 1)[-1] + if local_attr in _BAKE_REQUIRED_VISUAL_PROPERTIES: + issues.add( + f"{label} uses Bake-required visual attribute {local_attr!r}; " + "bake the effect or rebuild it with supported geometry" + ) + + for name in _ALPHA_PROPERTIES: + direct_value = elem.get(name) + if direct_value is not None and _finite_unit_interval(direct_value) is None: + issues.add( + f"{label} {name} must be a finite unitless number from " + f"0 to 1; got {direct_value!r}" + ) + for style_name, style_value in style_declarations: + if style_name == name and _finite_unit_interval(style_value) is None: + issues.add( + f"{label} style {name} must be a finite unitless number " + f"from 0 to 1; got {style_value!r}" + ) + + if _local_name(elem).lower() != 'g': + continue + style_opacity = next(( + value for name, value in reversed(style_declarations) + if name == 'opacity' + ), None) + raw_opacity = style_opacity if style_opacity is not None else elem.get('opacity') + if raw_opacity is None: + continue + opacity = _finite_unit_interval(raw_opacity) + if opacity is not None and opacity < 1.0: + issues.add( + f"{label} uses ; generated SVG " + "must put alpha on individual descendants because native " + "PPTX export cannot preserve isolated group compositing" + ) + + result['errors'].extend(sorted(issues)) + + def _check_definition_contract( + self, + root: ET.Element, + result: Dict, + ) -> None: + """Require conditional definitions to be direct, uniquely identified defs.""" + parent_by_id = { + id(child): parent + for parent in root.iter() + for child in list(parent) + } + definitions, duplicate_definition_ids = _direct_defs_index(root) + issues = { + f'Duplicate direct id {definition_id!r} makes local references ambiguous' + for definition_id in duplicate_definition_ids + } + all_id_counts = Counter( + elem.get('id') + for elem in root.iter() + if (elem.get('id') or '').strip() + ) + for definition_id in definitions: + if all_id_counts[definition_id] > 1: + issues.add( + f'Definition id {definition_id!r} is duplicated in the SVG; ' + 'local references require one unique target' + ) + + for elem in root.iter(): + tag = _local_name(elem) + if tag not in _DEFINITION_TAGS: + continue + label = _element_label(elem) + parent = parent_by_id.get(id(elem)) + if parent is None or _local_name(parent) != 'defs': + issues.add( + f"{label} must be a direct child of " + ) + if not (elem.get('id') or '').strip(): + issues.add(f"{label} requires a non-empty unique id") + + result['errors'].extend(sorted(issues)) + + def _check_marker_contract( + self, + root: ET.Element, + result: Dict, + ) -> None: + """Validate marker references against the native line-end contract.""" + definitions, _duplicates = _direct_defs_index(root) + parent_by_id = { + id(child): parent + for parent in root.iter() + for child in list(parent) + } + issues: set[str] = set() + checked_markers: set[str] = set() + + for elem in root.iter(): + for attr in ('marker-start', 'marker-end'): + raw_ref = elem.get(attr) + if raw_ref is None or raw_ref.strip().lower() == 'none': + continue + label = _element_label(elem) + tag = _local_name(elem).lower() + if tag not in {'line', 'path'}: + issues.add( + f"{label} {attr} is allowed only on or " + ) + match = re.fullmatch(r'url\(#([^)]+)\)', raw_ref.strip()) + if match is None: + issues.add( + f"{label} {attr} must be an exact local url(#id) reference; " + f"got {raw_ref!r}" + ) + continue + marker_id = match.group(1) + marker = definitions.get(marker_id) + if marker is None or _local_name(marker) != 'marker': + issues.add( + f"{label} {attr}=url(#{marker_id}) has no matching direct " + f" definition" + ) + continue + + visual_children = [ + child for child in list(marker) + if _local_name(child) not in _NON_VISUAL_SVG_TAGS + ] + shape = visual_children[0] if len(visual_children) == 1 else None + if marker_id not in checked_markers: + checked_markers.add(marker_id) + marker_label = f'' + if marker.get('orient') != 'auto': + issues.add(f'{marker_label} requires orient="auto"') + marker_units = marker.get('markerUnits', 'strokeWidth') + if marker_units not in {'strokeWidth', 'userSpaceOnUse'}: + issues.add( + f"{marker_label} has unsupported markerUnits={marker_units!r}" + ) + for size_attr in ('markerWidth', 'markerHeight'): + raw_size = marker.get(size_attr) + if raw_size is None: + continue + try: + size = float(raw_size) + except ValueError: + size = math.nan + if not math.isfinite(size) or size <= 0: + issues.add( + f"{marker_label} {size_attr} must be a positive " + f"finite number; got {raw_size!r}" + ) + if shape is None: + issues.add( + f"{marker_label} must contain exactly one direct " + "triangle/diamond path or polygon, circle, or ellipse" + ) + else: + shape_tag = _local_name(shape).lower() + if shape.get('transform'): + issues.add( + f"{marker_label} child <{shape_tag}> cannot use transform" + ) + if shape_tag == 'path': + path_data = shape.get('d', '') + if not ( + _MARKER_TRIANGLE_PATH_RE.fullmatch(path_data) + or _MARKER_DIAMOND_PATH_RE.fullmatch(path_data) + ): + issues.add( + f"{marker_label} path must be a closed 3- or " + "4-vertex path with one explicit M/L command " + "per vertex" + ) + elif shape_tag == 'polygon': + vertex_count = _marker_polygon_vertex_count( + shape.get('points', '') + ) + if vertex_count not in {3, 4}: + issues.add( + f"{marker_label} polygon must contain exactly " + "3 or 4 finite vertices" + ) + elif shape_tag not in {'circle', 'ellipse'}: + issues.add( + f"{marker_label} child <{shape_tag}> has no native " + "line-end mapping" + ) + + if shape is None or _parse_export_color is None: + continue + stroke_value = _effective_presentation_value( + elem, 'stroke', parent_by_id, + ) + marker_fill = _effective_presentation_value( + shape, 'fill', parent_by_id, + ) or '#000000' + stroke_color, _stroke_alpha = _parse_export_color(stroke_value or '') + fill_color, _fill_alpha = _parse_export_color(marker_fill) + if stroke_color is None or fill_color is None: + issues.add( + f"{label} {attr} marker fill and line stroke must both be " + "supported solid colors" + ) + elif stroke_color != fill_color: + issues.add( + f"{label} {attr}=url(#{marker_id}) marker fill " + f"{marker_fill!r} does not match effective line stroke " + f"{stroke_value!r}" + ) + + result['errors'].extend(sorted(issues)) + + def _check_clip_path_contract( + self, + root: ET.Element, + result: Dict, + ) -> None: + """Validate image clip paths against the native picture geometry mapping.""" + definitions, _duplicates = _direct_defs_index(root) + issues: set[str] = set() + checked_clips: set[str] = set() + for elem in root.iter(): + raw_ref = elem.get('clip-path') + if raw_ref is None or raw_ref.strip().lower() == 'none': + continue + label = _element_label(elem) tag = _local_name(elem).lower() - if tag not in {'g', 'image'}: + is_imported_crop = tag == 'svg' and elem.get('data-pptx-crop') == '1' + if tag != 'image' and not is_imported_crop: + issues.add( + f"{label} clip-path is allowed only on or an imported " + "data-pptx-crop=\"1\" wrapper" + ) + match = re.fullmatch(r'url\(#([^)]+)\)', raw_ref.strip()) + if match is None: + issues.add( + f"{label} clip-path must be an exact local url(#id) " + f"reference; got {raw_ref!r}" + ) continue - raw_opacity = elem.get('opacity') - if raw_opacity is None: - style_match = re.search( - r'(?:^|;)\s*opacity\s*:\s*([^;]+)', - elem.get('style', ''), - flags=re.IGNORECASE, + clip_id = match.group(1) + clip = definitions.get(clip_id) + if clip is None or _local_name(clip) != 'clipPath': + issues.add( + f"{label} clip-path=url(#{clip_id}) has no matching direct " + f" definition" ) - raw_opacity = style_match.group(1).strip() if style_match else None - if raw_opacity is None: continue - try: - opacity = float(raw_opacity) - except ValueError: - opacity = -1.0 - if not 0.0 <= opacity <= 1.0: - result['errors'].append( - f"<{tag} opacity> must be a numeric value from 0 to 1, got {raw_opacity!r}" + if clip_id in checked_clips: + continue + checked_clips.add(clip_id) + clip_label = f'' + clip_units = clip.get('clipPathUnits', 'userSpaceOnUse') + if clip_units not in {'userSpaceOnUse', 'objectBoundingBox'}: + issues.add( + f"{clip_label} has unsupported clipPathUnits={clip_units!r}" ) - if tag == 'g' and opacity < 1.0 and any( - descendant.tag.rsplit('}', 1)[-1] != 'metadata' - and descendant.get('data-pptx-native') - for descendant in elem.iter() - ): - result['warnings'].append( - " around data-pptx-native content uses the SVG " - "fallback; --native-objects export rejects that combination" + if clip.get('transform'): + issues.add(f"{clip_label} cannot use transform") + visual_children = [ + child for child in list(clip) + if _local_name(child) not in _NON_VISUAL_SVG_TAGS + ] + if len(visual_children) != 1: + issues.add( + f"{clip_label} must contain exactly one direct supported shape" ) + continue + shape = visual_children[0] + shape_tag = _local_name(shape).lower() + if shape_tag not in _CLIP_SHAPE_TAGS: + issues.add( + f"{clip_label} child <{shape_tag}> is unsupported; use " + "circle, ellipse, rect, path, or polygon" + ) + if shape.get('transform'): + issues.add( + f"{clip_label} child <{shape_tag}> cannot use transform" + ) + + result['errors'].extend(sorted(issues)) def _check_filter_effects(self, root: ET.Element, result: Dict) -> None: """Validate filters against the native shadow/glow approximation.""" elems = list(root.iter()) - direct_filters = [] - filters_by_id = {} - for defs_elem in elems: - if _local_name(defs_elem) != 'defs': - continue - for child in defs_elem: - if _local_name(child) != 'filter': - continue - direct_filters.append(child) - filter_id = child.get('id') - if filter_id: - filters_by_id[filter_id] = child + definitions, _duplicates = _direct_defs_index(root) + direct_filters = [ + elem for elem in definitions.values() + if _local_name(elem) == 'filter' + ] + filters_by_id = { + filter_id: elem + for filter_id, elem in definitions.items() + if _local_name(elem) == 'filter' + } issues = set() for elem in elems: - tag = _local_name(elem) + tag = _local_name(elem).lower() + label = _element_label(elem) style_values = ( _parse_inline_style(elem.get('style')) if _parse_inline_style is not None else {} ) if style_values.get('filter'): issues.add( - f"<{tag}> filter must use a direct filter=\"url(#id)\" " + f"{label} filter must use a direct filter=\"url(#id)\" " "attribute; inline style filters are not supported" ) raw_filter = elem.get('filter') if raw_filter is None: continue + if tag not in _FILTER_PUBLIC_TARGETS: + issues.add( + f"{label} cannot use filter; supported native targets are " + "rect, circle, path, and text" + ) match = re.fullmatch(r'url\(#([^)]+)\)', raw_filter.strip()) if match is None: issues.add( - f"<{tag}> filter must be an exact local url(#id) reference; " + f"{label} filter must be an exact local url(#id) reference; " f"got {raw_filter!r}" ) continue filter_id = match.group(1) if filter_id not in filters_by_id: issues.add( - f"<{tag}> filter=url(#{filter_id}) has no matching direct " + f"{label} filter=url(#{filter_id}) has no matching direct " f" definition" ) @@ -1246,10 +1749,19 @@ class SVGQualityChecker: f"{label} uses unsupported filter primitive(s): " f"{', '.join(unsupported)}" ) - if not _FILTER_EFFECT_PRIMITIVES.intersection(primitives): + effect_primitives = [ + primitive for primitive in primitives + if primitive in _FILTER_EFFECT_PRIMITIVES + ] + if not effect_primitives: issues.add( f"{label} must contain feDropShadow or feGaussianBlur" ) + elif len(effect_primitives) > 1: + issues.add( + f"{label} contains multiple shadow/glow primitives; one " + "filter must map to exactly one native effect" + ) if any( _local_name(descendant) == 'feFuncA' and descendant.get('type') != 'linear' @@ -1257,10 +1769,44 @@ class SVGQualityChecker: ): issues.add(f"{label} requires feFuncA type=\"linear\"") + for primitive in filter_elem.iter(): + primitive_tag = _local_name(primitive) + numeric_attrs: tuple[tuple[str, bool], ...] = () + if primitive_tag in {'feDropShadow', 'feGaussianBlur'}: + numeric_attrs = (('stdDeviation', True),) + elif primitive_tag == 'feOffset': + numeric_attrs = (('dx', False), ('dy', False)) + elif primitive_tag == 'feFuncA': + numeric_attrs = (('slope', True),) + if primitive_tag == 'feDropShadow': + numeric_attrs += (('dx', False), ('dy', False)) + for attr_name, non_negative in numeric_attrs: + raw_value = primitive.get(attr_name) + if raw_value is None: + continue + try: + value = float(raw_value) + except ValueError: + value = math.nan + if ( + not math.isfinite(value) + or (non_negative and value < 0) + or ( + primitive_tag == 'feFuncA' + and attr_name == 'slope' + and value > 1 + ) + ): + qualifier = ' from 0 to 1' if primitive_tag == 'feFuncA' else '' + issues.add( + f"{label} <{primitive_tag}> {attr_name} must be a " + f"finite number{qualifier}; got {raw_value!r}" + ) + result['errors'].extend(sorted(issues)) def _check_gradient_interfaces(self, root: ET.Element, result: Dict) -> None: - """Reject gradient inheritance, transforms, and spread modes.""" + """Validate the normalized native gradient authoring interface.""" issues = set() for gradient in root.iter(): tag = _local_name(gradient) @@ -1281,6 +1827,59 @@ class SVGQualityChecker: issues.add(f"{label} cannot use gradientTransform") if 'spreadMethod' in attribute_names: issues.add(f"{label} cannot use spreadMethod") + gradient_units = gradient.get('gradientUnits') + if gradient_units not in {None, 'objectBoundingBox'}: + issues.add( + f"{label} cannot use gradientUnits={gradient_units!r}; " + "use normalized objectBoundingBox coordinates" + ) + + coordinate_names = ( + ('x1', 'y1', 'x2', 'y2') + if tag == 'linearGradient' + else ('cx', 'cy', 'r', 'fx', 'fy') + ) + for coordinate_name in coordinate_names: + raw_coordinate = gradient.get(coordinate_name) + if raw_coordinate is None: + continue + coordinate = _normalized_gradient_value(raw_coordinate) + if coordinate is None: + issues.add( + f"{label} {coordinate_name} must be a normalized finite " + f"value from 0 to 1 or 0% to 100%; got {raw_coordinate!r}" + ) + elif coordinate_name == 'r' and coordinate <= 0: + issues.add(f"{label} r must be greater than 0") + + stops = [] + for child in list(gradient): + child_tag = _local_name(child) + if child_tag in _NON_VISUAL_SVG_TAGS: + continue + if child_tag != 'stop': + issues.add( + f"{label} has unsupported direct child <{child_tag}>; " + "gradient definitions may contain only direct children" + ) + continue + stops.append(child) + if not stops: + issues.add(f"{label} requires at least one direct child") + for index, stop in enumerate(stops, start=1): + stop_label = f"{label} stop #{index}" + raw_offset = stop.get('offset') + if raw_offset is None or _normalized_gradient_value(raw_offset) is None: + issues.add( + f"{stop_label} offset must be explicit and within 0..1 " + f"or 0%..100%; got {raw_offset!r}" + ) + style_values = ( + _parse_inline_style(stop.get('style')) + if _parse_inline_style is not None else {} + ) + if not (style_values.get('stop-color') or stop.get('stop-color')): + issues.add(f"{stop_label} requires an explicit stop-color") result['errors'].extend(sorted(issues)) @@ -1785,9 +2384,8 @@ class SVGQualityChecker: preset name comes from `data-pptx-pattern` (e.g. `lgGrid` / `smGrid` / `dkUpDiag`). Two failure modes worth catching pre-export: - 1. Missing annotation → converter silently falls back to `ltUpDiag` - (diagonal stripes). Color metadata or child paints still resolve, - with white as the final background fallback. + 1. Missing annotation → the converter compatibility fallback chooses + `ltUpDiag` (diagonal stripes), which is not an authoring contract. 2. Invalid preset name → PPTX schema rejects the file; PowerPoint opens it with "needs to be repaired". OOXML `ST_PresetPatternVal` is a closed enum — only the names in @@ -1795,19 +2393,44 @@ class SVGQualityChecker: value) is the canonical mistake; the only grids are `smGrid` / `lgGrid` / `dotGrid`. """ - for pattern in root.iter(f'{{{SVG_NS}}}pattern'): + definitions, _duplicates = _direct_defs_index(root) + referenced_patterns: set[str] = set() + for elem in root.iter(): + style_values = ( + _parse_inline_style(elem.get('style')) + if _parse_inline_style is not None else {} + ) + fill = style_values.get('fill') or elem.get('fill') + match = re.fullmatch(r'url\(#([^)]+)\)', (fill or '').strip()) + if match is None: + continue + definition = definitions.get(match.group(1)) + if definition is not None and _local_name(definition) == 'pattern': + referenced_patterns.add(match.group(1)) + + for pattern in ( + elem for elem in root.iter() + if _local_name(elem) == 'pattern' + ): pat_id = pattern.get('id', '') prst = pattern.get('data-pptx-pattern') - if not prst: - result['warnings'].append( + if pat_id in referenced_patterns and not prst: + result['errors'].append( f" has no data-pptx-pattern attribute — " - "PPTX export will fall back to `ltUpDiag` (diagonal stripes), " - "not your custom geometry. Add a valid data-pptx-pattern; " + "generated SVG cannot rely on the converter's `ltUpDiag` " + "compatibility fallback. Add a valid data-pptx-pattern; " "set data-pptx-fg/data-pptx-bg or matching child paints " "when explicit pattern colors are required." ) continue + if pat_id in referenced_patterns and pattern.get('patternTransform'): + result['errors'].append( + f" cannot use patternTransform; " + "the native preset mapping does not preserve custom tile transforms" + ) if prst not in self._OOXML_PATTERN_PRESETS: + if not prst: + continue result['errors'].append( f" uses data-pptx-pattern=\"{prst}\" " "which is not in OOXML ST_PresetPatternVal — exported PPTX " @@ -1949,6 +2572,28 @@ class SVGQualityChecker: result: Dict, ) -> None: """Validate the intrinsic structured Master/Layout SVG contract.""" + if not self.template_mode and svg_path.parent.name == 'svg_output': + declared_mode = _declared_pptx_structure_mode( + self._resolve_project_path(svg_path) + ) + if declared_mode == 'flat': + forbidden_attrs = sorted({ + attr + for elem in root.iter() + for attr in _PPTX_STRUCTURE_ATTRS + if elem.get(attr) is not None + }) + if forbidden_attrs: + result['errors'].append( + f"{svg_path.name}: pptx_structure.mode: flat forbids " + "Master/Layout/layer/placeholder metadata; remove " + + ', '.join(forbidden_attrs) + ) + return + if declared_mode != 'structured': + # The project-level gate emits one actionable migration error. + # Avoid burying it under repeated per-page structure failures. + return has_structure_metadata = any( elem.get(attr) is not None for elem in root.iter() @@ -2418,6 +3063,8 @@ class SVGQualityChecker: if not dir_path.exists(): print(f"[ERROR] Directory does not exist: {directory}") + self.summary['errors'] += 1 + self.issue_types['Input issues'] += 1 return [] # Brand-only template workspaces have no SVG roster. Resolve the current @@ -2451,7 +3098,9 @@ class SVGQualityChecker: svg_files = sorted(svg_output.glob('*.svg')) if not svg_files: - print(f"[WARN] No SVG files found") + print(f"[ERROR] No SVG files found in: {directory}") + self.summary['errors'] += 1 + self.issue_types['Input issues'] += 1 return [] print(f"\n[SCAN] Checking {len(svg_files)} SVG file(s)...\n") @@ -2460,10 +3109,19 @@ class SVGQualityChecker: result = self.check_file(str(svg_file), expected_format) self._print_result(result) - self._check_pptx_structure_contract(dir_path, svg_files) - if self.template_mode and dir_path.is_dir(): - self._check_template_contract(dir_path, svg_files) - elif dir_path.is_dir(): + if self.template_mode: + check_structure = _template_structure_checks_enabled(dir_path) + if check_structure: + self._check_pptx_structure_contract(dir_path, svg_files) + if dir_path.is_dir(): + self._check_template_contract( + dir_path, + svg_files, + check_structure=check_structure, + ) + elif _CHECK_PPTX_STRUCTURED_PROJECT: + self._check_pptx_structure_contract(dir_path, svg_files) + if not self.template_mode and dir_path.is_dir(): self._check_animation_config_contract(dir_path) self._check_illustration_resource_contract(dir_path) @@ -2480,6 +3138,39 @@ class SVGQualityChecker: not self.template_mode and (project_path / 'svg_output').is_dir() ) + declared_mode = ( + _declared_pptx_structure_mode(project_path) + if standard_project + else None + ) + if standard_project and declared_mode in {'flat', 'structured'}: + self._pptx_structure_issues.extend( + ('error', message) + for message in _generated_theme_contract_errors(project_path) + ) + if standard_project and declared_mode == 'flat': + if ( + _load_pptx_structure_lock is None + or _TemplateStructureError is None + ): + self._pptx_structure_issues.append(( + 'error', + 'Flat PPTX project validation is unavailable because the ' + 'template_structure module could not be imported.', + )) + return + try: + structure_lock = _load_pptx_structure_lock(project_path) + except _TemplateStructureError as exc: + self._pptx_structure_issues.append(('error', str(exc))) + return + if structure_lock is None or structure_lock.mode != 'flat': + self._pptx_structure_issues.append(( + 'error', + 'spec_lock.md must contain one complete ' + 'pptx_structure.mode: flat contract.', + )) + return has_metadata = False for svg_path in svg_files: try: @@ -2527,16 +3218,18 @@ class SVGQualityChecker: ) return - declared_mode = _declared_pptx_structure_mode(project_path) if standard_project and declared_mode != 'structured': label = repr(declared_mode) if declared_mode else ( 'missing (legacy implicit baseline)' ) self._pptx_structure_issues.append(( 'error', - 'release SVG projects require spec_lock.md ' - f'pptx_structure.mode: structured; found {label}. Follow ' - 'skills/ppt-master/workflows/restore-pptx-structure.md before export.', + 'release SVG projects require an explicit spec_lock.md ' + 'pptx_structure.mode: flat (free design / brand-only) or ' + f'structured (deck/layout template); found {label}. New ' + 'free-design projects use mode: flat; restore legacy ' + 'template/structured metadata by following skills/ppt-master/' + 'workflows/restore-pptx-structure.md before export.', )) return @@ -2616,18 +3309,31 @@ class SVGQualityChecker: master.master_key: master.master_name for master in structure_lock.masters } + definitions = { + definition.layout_key: definition + for definition in structure_lock.layout_definitions + } errors: List[str] = [] for spec in specs: page = f"P{spec.slide_num:02d}" reference = references.get(spec.slide_num) if reference is None: - errors.append(f"spec_lock.md pptx_layouts is missing {page}") + errors.append( + f"spec_lock.md page_pptx_layouts is missing {page}" + ) continue - if spec.master_key != reference.master_key: + definition = definitions.get(reference.layout_key) + if definition is None: + errors.append( + f"spec_lock.md pptx_layouts is missing Layout " + f"{reference.layout_key!r}" + ) + continue + if spec.master_key != definition.master_key: errors.append( f"{spec.svg_path.name}: data-pptx-master={spec.master_key!r} " - f"does not match spec_lock {page} Master key " - f"{reference.master_key!r}" + f"does not match spec_lock Layout {reference.layout_key!r} " + f"Master key {definition.master_key!r}" ) if spec.layout_key != reference.layout_key: errors.append( @@ -2635,11 +3341,11 @@ class SVGQualityChecker: f"does not match spec_lock {page} layout key " f"{reference.layout_key!r}" ) - if spec.layout_name != reference.layout_name: + if spec.layout_name != definition.layout_name: errors.append( f"{spec.svg_path.name}: data-pptx-layout-name=" - f"{spec.layout_name!r} does not match spec_lock {page} " - f"layout name {reference.layout_name!r}" + f"{spec.layout_name!r} does not match spec_lock Layout " + f"{reference.layout_key!r} name {definition.layout_name!r}" ) expected_master_name = master_names.get(spec.master_key) if expected_master_name != spec.master_name: @@ -3222,14 +3928,21 @@ class SVGQualityChecker: ) self._animation_issues.append((severity, message)) - def _check_template_contract(self, dir_path: Path, - svg_files: List[Path]) -> None: + def _check_template_contract( + self, + dir_path: Path, + svg_files: List[Path], + *, + check_structure: bool, + ) -> None: """Check reusable-template structure, roster, and placeholder hints. - **Roster mismatch (orphan / missing)** is reported as an *error*: a stale roster will produce a wrong ``layouts_index.json`` entry. - - **Explicit structure gaps** are errors: every reusable SVG declares - its Master and Layout identity. Zero-placeholder Layouts are valid. + - **Explicit structure gaps** are errors when positive structure checks + are enabled: every current reusable SVG declares its Master and Layout + identity. Zero-placeholder Layouts are valid. Legacy template-mode + packages fail and must run the structure-restoration workflow. - **Placeholder gaps** are reported as *warnings*. Templates may legitimately omit conventional placeholders or swap them out (e.g. ``{{CLOSING_MESSAGE}}`` instead of ``{{THANK_YOU}}``), and a content @@ -3240,107 +3953,114 @@ class SVGQualityChecker: Issues are aggregated and printed in :py:meth:`print_summary` so the per-file report stays focused on intrinsic SVG validity. """ - native_contract_path = dir_path / 'native_structure.json' - source_template_path = dir_path / 'source_template.pptx' - legacy_structure_detected = False - for svg_file in svg_files: - try: - root = ET.parse(svg_file).getroot() - except (OSError, ET.ParseError): - continue - if not root.get('data-pptx-master'): - legacy_structure_detected = True - self._template_issues.append(( - 'error', - 'explicit_master_missing', - f"{svg_file.name}: reusable templates require root " - "data-pptx-master metadata", - )) - if not root.get('data-pptx-master-name'): - legacy_structure_detected = True - self._template_issues.append(( - 'error', - 'explicit_master_name_missing', - f"{svg_file.name}: reusable templates require root " - "data-pptx-master-name metadata", - )) - if not root.get('data-pptx-layout'): - self._template_issues.append(( - 'error', - 'explicit_structure_missing', - f"{svg_file.name}: reusable templates require root " - "data-pptx-layout metadata", - )) - if not root.get('data-pptx-layout-name'): - self._template_issues.append(( - 'error', - 'explicit_structure_name_missing', - f"{svg_file.name}: reusable templates require root " - "data-pptx-layout-name metadata", - )) - if root.get('data-pptx-layout-kind') is not None: - legacy_structure_detected = True - self._template_issues.append(( - 'error', - 'deck_instance_layout_kind', - f"{svg_file.name}: reusable template prototypes must omit " - "legacy data-pptx-layout-kind metadata", - )) - if any( - child.get('data-pptx-placeholder') is not None - and child.tag.rsplit('}', 1)[-1] != 'g' - for child in list(root) - ): - legacy_structure_detected = True - missing_bounds = [ - child.get('id') or child.tag.rsplit('}', 1)[-1] - for child in list(root) - if child.get('data-pptx-placeholder') is not None - and child.get('data-pptx-placeholder-bounds') is None - ] - if missing_bounds: - legacy_structure_detected = True - self._template_issues.append(( - 'error', - 'placeholder_bounds_missing', - f"{svg_file.name}: reusable templates require " - "explicit design-zone data-pptx-placeholder-bounds; missing: " - + ', '.join(missing_bounds), - )) - if native_contract_path.exists() or source_template_path.exists(): - legacy_structure_detected = True - self._template_issues.append(( - 'error', - 'legacy_native_structure_pair', - "legacy native_structure.json/source_template.pptx template " - "contracts must be restored through " - "skills/ppt-master/workflows/restore-pptx-structure.md", - )) - spec_path = dir_path / 'design_spec.md' spec_text = spec_path.read_text(encoding='utf-8') if spec_path.exists() else "" - mode_match = re.search( - r'^native_structure_mode:\s*([A-Za-z0-9_-]+)\s*$', - spec_text, - re.MULTILINE, - ) - declared_structure_mode = mode_match.group(1).lower() if mode_match else None + declared_structure_mode = _declared_template_structure_mode(dir_path) + mode_error_recorded = False if declared_structure_mode != 'structured': - legacy_structure_detected = True + mode_error_recorded = True self._template_issues.append(( 'error', 'explicit_structure_mode', "design_spec.md frontmatter must declare " - "native_structure_mode: structured", - )) - if legacy_structure_detected: - self._template_issues.append(( - 'error', - 'legacy_structure_contract', - "legacy template structure detected; run " - "skills/ppt-master/workflows/restore-pptx-structure.md before " - "Step 3 consumption", + "native_structure_mode: structured; legacy template-mode " + "workspaces must run restore-pptx-structure", )) + if check_structure: + native_contract_path = dir_path / 'native_structure.json' + source_template_path = dir_path / 'source_template.pptx' + legacy_structure_detected = False + for svg_file in svg_files: + try: + root = ET.parse(svg_file).getroot() + except (OSError, ET.ParseError): + continue + if not root.get('data-pptx-master'): + legacy_structure_detected = True + self._template_issues.append(( + 'error', + 'explicit_master_missing', + f"{svg_file.name}: reusable templates require root " + "data-pptx-master metadata", + )) + if not root.get('data-pptx-master-name'): + legacy_structure_detected = True + self._template_issues.append(( + 'error', + 'explicit_master_name_missing', + f"{svg_file.name}: reusable templates require root " + "data-pptx-master-name metadata", + )) + if not root.get('data-pptx-layout'): + self._template_issues.append(( + 'error', + 'explicit_structure_missing', + f"{svg_file.name}: reusable templates require root " + "data-pptx-layout metadata", + )) + if not root.get('data-pptx-layout-name'): + self._template_issues.append(( + 'error', + 'explicit_structure_name_missing', + f"{svg_file.name}: reusable templates require root " + "data-pptx-layout-name metadata", + )) + if root.get('data-pptx-layout-kind') is not None: + legacy_structure_detected = True + self._template_issues.append(( + 'error', + 'deck_instance_layout_kind', + f"{svg_file.name}: reusable template prototypes must omit " + "legacy data-pptx-layout-kind metadata", + )) + if any( + child.get('data-pptx-placeholder') is not None + and child.tag.rsplit('}', 1)[-1] != 'g' + for child in list(root) + ): + legacy_structure_detected = True + missing_bounds = [ + child.get('id') or child.tag.rsplit('}', 1)[-1] + for child in list(root) + if child.get('data-pptx-placeholder') is not None + and child.get('data-pptx-placeholder-bounds') is None + ] + if missing_bounds: + legacy_structure_detected = True + self._template_issues.append(( + 'error', + 'placeholder_bounds_missing', + f"{svg_file.name}: reusable templates require " + "explicit design-zone data-pptx-placeholder-bounds; missing: " + + ', '.join(missing_bounds), + )) + if native_contract_path.exists() or source_template_path.exists(): + legacy_structure_detected = True + self._template_issues.append(( + 'error', + 'legacy_native_structure_pair', + "legacy native_structure.json/source_template.pptx template " + "contracts must be restored through " + "skills/ppt-master/workflows/restore-pptx-structure.md", + )) + + if declared_structure_mode != 'structured': + legacy_structure_detected = True + if not mode_error_recorded: + self._template_issues.append(( + 'error', + 'explicit_structure_mode', + "design_spec.md frontmatter must declare " + "native_structure_mode: structured", + )) + if legacy_structure_detected: + self._template_issues.append(( + 'error', + 'legacy_structure_contract', + "legacy template structure detected; run " + "skills/ppt-master/workflows/restore-pptx-structure.md before " + "Step 3 consumption", + )) spec_pages = self._extract_spec_roster(spec_text) if spec_text else [] custom_contract = self._extract_frontmatter_placeholders(spec_text) if spec_text else {} @@ -3364,9 +4084,9 @@ class SVGQualityChecker: )) elif spec_path.exists(): # design_spec.md is present but the roster parser found nothing — - # surface as a warning. Legacy specs may lack an explicit roster. + # reusable template workspaces always fail closed. self._template_issues.append(( - 'warning', + 'error', 'roster_unknown', f"could not extract page roster from {spec_path.name}; " "skipping orphan/missing checks", @@ -3835,20 +4555,23 @@ def print_usage() -> None: print("Usage:") print(" python3 scripts/svg_quality_checker.py ") print(" python3 scripts/svg_quality_checker.py ") - print(" python3 scripts/svg_quality_checker.py --template-mode") + print(" python3 scripts/svg_quality_checker.py /templates --template-mode") print(" python3 scripts/svg_quality_checker.py --all examples") print("\nExamples:") print(" python3 scripts/svg_quality_checker.py examples/project/svg_output/slide_01.svg") print(" python3 scripts/svg_quality_checker.py examples/project/svg_output") print(" python3 scripts/svg_quality_checker.py examples/project") - print(" python3 scripts/svg_quality_checker.py templates/layouts/academic_defense --template-mode") - print(" python3 scripts/svg_quality_checker.py templates/decks/招商银行 --template-mode") + print(" python3 scripts/svg_quality_checker.py templates/layouts/presentation_core/templates --template-mode") + print(" python3 scripts/svg_quality_checker.py templates/decks/中国电信/templates --template-mode") print("\nOptions:") print(" --format Expected canvas format") - print(" --template-mode Validate a templates/{layouts,decks}/ directory:") - print(" glob *.svg directly, skip spec_lock checks,") - print(" enforce roster ↔ design_spec.md Page Roster consistency,") - print(" and emit advisory placeholder-convention warnings.") + print(" --template-mode Validate a template workspace's templates/ directory:") + print(" glob *.svg directly and skip spec_lock checks;") + print(" always enforce roster consistency and emit placeholder hints.") + print(" native_structure_mode: structured also enables complete") + print(" per-file and cross-page structure validation. Legacy") + print(" native_structure_mode: template fails and must run") + print(" restore-pptx-structure before validation.") def main() -> None: diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/drawingml/theme_fonts.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/drawingml/theme_fonts.py index 6ec97880..4e00da36 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/drawingml/theme_fonts.py +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/drawingml/theme_fonts.py @@ -48,11 +48,22 @@ class ThemeFontSpec: @dataclass(frozen=True) class MasterTextStyleSpec: - """Title/body defaults written to a template slide master's txStyles.""" + """Title/body defaults written to one generated slide master's txStyles.""" title_hpt: int body_hpt: int + @property + def body_levels_hpt(self) -> tuple[int, ...]: + """Return a deterministic nine-level PowerPoint body-size hierarchy.""" + factors = (16, 15, 14, 13, 12, 11, 10, 9, 8) + minimum = min(self.body_hpt, 800) + sizes = [] + for factor in factors: + scaled = round((self.body_hpt * factor / 16) / 50) * 50 + sizes.append(max(minimum, scaled)) + return tuple(sizes) + def _font_face(font_family: str) -> ThemeFontFace: fonts = parse_font_family(font_family) @@ -125,17 +136,17 @@ def _font_size_hpt(raw: str, field: str) -> int: def load_master_text_style_spec(project_path: Path) -> MasterTextStyleSpec: - """Load required title/body defaults for explicit Layout master txStyles.""" + """Load required title/body defaults for generated Master text styles.""" lock_path = project_path / "spec_lock.md" if not lock_path.is_file(): raise ThemeFontError( - "explicit Layout export requires spec_lock.md typography title and body rows" + "Master export requires spec_lock.md typography title and body rows" ) rows = _typography_rows(lock_path) missing = [field for field in ("title", "body") if field not in rows] if missing: raise ThemeFontError( - "explicit Layout export requires spec_lock.md typography rows: " + "Master export requires spec_lock.md typography rows: " + ", ".join(missing) ) return MasterTextStyleSpec( @@ -213,11 +224,29 @@ def _style_run_properties(style: ET.Element, label: str) -> list[ET.Element]: return run_properties +def _style_level_run_properties( + style: ET.Element, + label: str, +) -> tuple[ET.Element, ...]: + """Return direct level 1-9 defaults from one Master text style.""" + levels: list[ET.Element] = [] + for level in range(1, 10): + run_properties = style.find( + f"{{{DML_NS}}}lvl{level}pPr/{{{DML_NS}}}defRPr" + ) + if run_properties is None: + raise ThemeFontError( + f"slide master {label} has no level-{level} a:defRPr" + ) + levels.append(run_properties) + return tuple(levels) + + def apply_master_text_style_spec( extract_dir: Path, spec: MasterTextStyleSpec, ) -> int: - """Install locked title/body sizes into template slide-master txStyles.""" + """Install locked title/body sizes into generated slide-master txStyles.""" master_dir = extract_dir / "ppt" / "slideMasters" master_paths = sorted(master_dir.glob("slideMaster*.xml")) if not master_paths: @@ -234,23 +263,39 @@ def apply_master_text_style_spec( if text_styles is None: raise ThemeFontError(f"Slide master has no p:txStyles: {master_path}") - style_sizes = ( - ("titleStyle", spec.title_hpt), - ("bodyStyle", spec.body_hpt), - ("otherStyle", spec.body_hpt), - ) - for style_name, size in style_sizes: + title_style = text_styles.find(f"{{{PML_NS}}}titleStyle") + if title_style is None: + raise ThemeFontError( + f"Slide master has no p:titleStyle: {master_path}" + ) + for run_properties in _style_run_properties( + title_style, + "p:titleStyle", + ): + run_properties.set("sz", str(spec.title_hpt)) + + body_levels = spec.body_levels_hpt + for style_name in ("bodyStyle", "otherStyle"): style = text_styles.find(f"{{{PML_NS}}}{style_name}") if style is None: raise ThemeFontError( f"Slide master has no p:{style_name}: {master_path}" ) - for run_properties in _style_run_properties( - style, - f"p:{style_name}", + for run_properties, size in zip( + _style_level_run_properties( + style, + f"p:{style_name}", + ), + body_levels, ): run_properties.set("sz", str(size)) + style_sizes = ( + ("titleStyle", (spec.title_hpt,)), + ("bodyStyle", body_levels), + ("otherStyle", body_levels), + ) + tree.write(master_path, encoding="utf-8", xml_declaration=True) try: @@ -264,20 +309,27 @@ def apply_master_text_style_spec( raise ThemeFontError( f"Slide master lost p:txStyles after update: {master_path}" ) - for style_name, expected_size in style_sizes: + for style_name, expected_sizes in style_sizes: style = read_back_styles.find(f"{{{PML_NS}}}{style_name}") - actual_sizes = ( - { + if style is None: + actual_sizes: tuple[str | None, ...] = () + elif style_name == "titleStyle": + actual_sizes = tuple( item.get("sz") for item in _style_run_properties( style, f"p:{style_name}", ) - } - if style is not None - else set() - ) - if actual_sizes != {str(expected_size)}: + ) + else: + actual_sizes = tuple( + item.get("sz") + for item in _style_level_run_properties( + style, + f"p:{style_name}", + ) + ) + if actual_sizes != tuple(str(size) for size in expected_sizes): raise ThemeFontError( f"Slide master p:{style_name} size read-back failed: " f"{master_path}" diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/pptx_package/builder.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/pptx_package/builder.py index 62dbabe2..481b86e1 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/pptx_package/builder.py +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/pptx_package/builder.py @@ -101,6 +101,7 @@ from .template_structure import ( TemplateElementSpec, TemplateSlideSpec, TemplateStructureError, + flat_structure_metadata_errors, is_proxy_placeholder, match_native_placeholders, parse_preserve_slides, @@ -112,9 +113,16 @@ from .template_validation import validate_pptx_template_package SLIDE_LAYOUT_REL_TYPE = ( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" ) +SLIDE_REL_TYPE = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide" +) SLIDE_MASTER_REL_TYPE = ( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" ) +THEME_REL_TYPE = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" +) +THEME_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.theme+xml" PML_NS = "http://schemas.openxmlformats.org/presentationml/2006/main" DML_NS = "http://schemas.openxmlformats.org/drawingml/2006/main" REL_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships" @@ -399,6 +407,7 @@ _TOP_LEVEL_SHAPE_TAGS = { f"{{{PML_NS}}}cxnSp", f"{{{PML_NS}}}graphicFrame", } +_FLAT_SYSTEM_PLACEHOLDER_TYPES = frozenset({"dt", "ftr", "sldNum"}) _REL_ATTRS = { f"{{{REL_NS}}}embed", f"{{{REL_NS}}}link", @@ -800,6 +809,7 @@ def _create_custom_layout( base_layout_path = extract_dir / base_layout_part tree = ET.parse(base_layout_path) root = tree.getroot() + _reseed_p14_creation_id(root) root.set("type", "cust") root.set("preserve", "1") root.set("showMasterSp", "1" if show_master_shapes else "0") @@ -896,6 +906,22 @@ def _set_master_picker_name(master_path: Path, master_name: str) -> None: _write_xml_tree(master_path, tree) +def _reseed_p14_creation_id(root: ET.Element) -> None: + """Give a cloned Slide/Master/Layout part a fresh PowerPoint creation id.""" + c_sld = root.find(f"{{{PML_NS}}}cSld") + if c_sld is None: + return + creation_ids = c_sld.findall( + f"{{{PML_NS}}}extLst/{{{PML_NS}}}ext/" + f"{{{P14_NS}}}creationId" + ) + for creation_id in creation_ids: + value = 0 + while value == 0: + value = uuid.uuid4().int & OOXML_UINT32_MAX + creation_id.set("val", str(value)) + + def _next_master_part_number(extract_dir: Path) -> int: numbers = [ int(match.group(1)) @@ -905,6 +931,103 @@ def _next_master_part_number(extract_dir: Path) -> int: return max(numbers, default=0) + 1 +def _next_theme_part_number(extract_dir: Path) -> int: + numbers = [ + int(match.group(1)) + for path in (extract_dir / "ppt" / "theme").glob("theme*.xml") + if (match := re.fullmatch(r"theme(\d+)\.xml", path.name)) + ] + return max(numbers, default=0) + 1 + + +def _clone_master_theme( + extract_dir: Path, + source_master_part: str, + master_part: str, + master_name: str, +) -> str: + """Give a cloned Slide Master its own Theme package part.""" + source_master_rels = _relationships_path_for_part( + extract_dir, + source_master_part, + ) + theme_targets = [ + attrs["Target"] + for attrs in _read_relationships(source_master_rels).values() + if attrs.get("Type") == THEME_REL_TYPE and attrs.get("Target") + ] + if len(theme_targets) != 1: + raise RuntimeError( + "Source Slide Master must have one Theme relationship: " + f"{source_master_part}" + ) + source_theme_part = _resolve_package_target( + source_master_part, + theme_targets[0], + ) + source_theme_path = extract_dir / source_theme_part + if not source_theme_path.exists(): + raise RuntimeError( + f"Slide Master Theme part is missing: {source_theme_part}" + ) + + theme_num = _next_theme_part_number(extract_dir) + theme_part = f"ppt/theme/theme{theme_num}.xml" + theme_path = extract_dir / theme_part + shutil.copyfile(source_theme_path, theme_path) + theme_tree = ET.parse(theme_path) + theme_tree.getroot().set("name", f"{master_name} Theme") + _write_xml_tree(theme_path, theme_tree) + + source_theme_rels = _relationships_path_for_part( + extract_dir, + source_theme_part, + ) + if source_theme_rels.exists(): + theme_rels = _relationships_path_for_part(extract_dir, theme_part) + theme_rels.parent.mkdir(parents=True, exist_ok=True) + shutil.copyfile(source_theme_rels, theme_rels) + + master_rels = _relationships_path_for_part(extract_dir, master_part) + theme_relationships = [ + (rel_id, attrs) + for rel_id, attrs in _read_relationships(master_rels).items() + if attrs.get("Type") == THEME_REL_TYPE + ] + if len(theme_relationships) != 1: + raise RuntimeError( + f"Cloned Slide Master must have one Theme relationship: {master_part}" + ) + theme_rel_id, _attrs = theme_relationships[0] + theme_target = posixpath.relpath(theme_part, posixpath.dirname(master_part)) + rels_content = master_rels.read_text(encoding="utf-8") + theme_rel_pattern = re.compile( + rf'(]*\bId="{re.escape(theme_rel_id)}"' + rf'[^>]*\bTarget=")[^"]*(")' + ) + rels_content, replaced = theme_rel_pattern.subn( + rf"\g<1>{theme_target}\g<2>", + rels_content, + count=1, + ) + if replaced != 1: + raise RuntimeError( + f"Could not retarget cloned Slide Master Theme: {master_part}" + ) + master_rels.write_text(rels_content, encoding="utf-8") + + content_types_path = extract_dir / "[Content_Types].xml" + content_types_path.write_text( + _add_content_type_override( + content_types_path.read_text(encoding="utf-8"), + theme_part, + THEME_CONTENT_TYPE, + ), + encoding="utf-8", + ) + return theme_part + + def _clone_structured_master( extract_dir: Path, source_master_part: str, @@ -919,6 +1042,7 @@ def _clone_structured_master( tree = ET.parse(master_path) root = tree.getroot() + _reseed_p14_creation_id(root) c_sld = root.find(f"{{{PML_NS}}}cSld") if c_sld is None: raise RuntimeError(f"Slide master has no p:cSld: {source_master_part}") @@ -939,6 +1063,12 @@ def _clone_structured_master( for rel_id, attrs in tuple(_read_relationships(master_rels).items()): if attrs.get("Type") == SLIDE_LAYOUT_REL_TYPE: _remove_relationship(master_rels, rel_id) + _clone_master_theme( + extract_dir, + source_master_part, + master_part, + master_name, + ) presentation_rels = extract_dir / "ppt" / "_rels" / "presentation.xml.rels" relationship_target = posixpath.relpath(master_part, "ppt") @@ -1981,6 +2111,95 @@ def _replace_shape_xfrm( sp_pr.insert(0, xfrm) +def _placeholder_vertical_anchor( + source_bounds: tuple[int, int, int, int], + target_bounds: tuple[int, int, int, int], +) -> str: + """Preserve an intentionally centered carrier inside its full slot frame.""" + _, source_y, _, source_height = source_bounds + _, target_y, _, target_height = target_bounds + source_center = source_y + source_height / 2 + target_center = target_y + target_height / 2 + return ( + "ctr" + if abs(source_center - target_center) <= target_height * 0.2 + else "t" + ) + + +def _normalize_placeholder_body_properties( + body_pr: ET.Element, + source_bounds: tuple[int, int, int, int], + target_bounds: tuple[int, int, int, int], +) -> None: + """Make a full-frame placeholder wrap text while preserving vertical intent.""" + body_pr.set("wrap", "square") + body_pr.set("anchor", _placeholder_vertical_anchor(source_bounds, target_bounds)) + body_pr.set("anchorCtr", "0") + autofit_tags = { + f"{{{DML_NS}}}noAutofit", + f"{{{DML_NS}}}normAutofit", + f"{{{DML_NS}}}spAutoFit", + } + for child in list(body_pr): + if child.tag in autofit_tags: + body_pr.remove(child) + body_pr.append(ET.Element(f"{{{DML_NS}}}noAutofit")) + + +def _apply_layout_frame_to_placeholder_carrier( + shape: ET.Element, + item: TemplateElementSpec, +) -> None: + """Use the reusable Layout bounds on one template-review Slide carrier.""" + if item.placeholder_bounds is None: + raise TemplateStructureError( + f"Placeholder {item.element_id!r} has no reusable Layout bounds" + ) + source_bounds = _shape_bounds_emu(shape, None) + target_bounds = _shape_bounds_emu(shape, item.placeholder_bounds) + if shape.tag in {f"{{{PML_NS}}}sp", f"{{{PML_NS}}}pic"}: + sp_pr = shape.find(f"{{{PML_NS}}}spPr") + if sp_pr is None: + raise TemplateStructureError( + f"Placeholder {item.element_id!r} has no p:spPr" + ) + _replace_shape_xfrm(sp_pr, target_bounds) + elif shape.tag == f"{{{PML_NS}}}graphicFrame": + xfrm = shape.find(f"{{{PML_NS}}}xfrm") + if xfrm is None: + xfrm = ET.Element(f"{{{PML_NS}}}xfrm") + shape.insert(1, xfrm) + for child in list(xfrm): + if child.tag in {f"{{{DML_NS}}}off", f"{{{DML_NS}}}ext"}: + xfrm.remove(child) + x, y, width, height = target_bounds + ET.SubElement(xfrm, f"{{{DML_NS}}}off", {"x": str(x), "y": str(y)}) + ET.SubElement( + xfrm, + f"{{{DML_NS}}}ext", + {"cx": str(width), "cy": str(height)}, + ) + else: + raise TemplateStructureError( + f"Placeholder {item.element_id!r} cannot use Layout bounds on " + f"DrawingML element {shape.tag.rsplit('}', 1)[-1]!r}" + ) + + tx_body = shape.find(f"{{{PML_NS}}}txBody") + if tx_body is None: + return + body_pr = tx_body.find(f"{{{DML_NS}}}bodyPr") + if body_pr is None: + body_pr = ET.Element(f"{{{DML_NS}}}bodyPr") + tx_body.insert(0, body_pr) + _normalize_placeholder_body_properties( + body_pr, + source_bounds, + target_bounds, + ) + + def _layout_level_one_paragraph_properties( list_style: ET.Element, ) -> ET.Element: @@ -2086,11 +2305,19 @@ def _placeholder_text_body( if source_tx_body is not None else None ) - tx_body.append( + body_pr = ( ET.fromstring(ET.tostring(source_body_pr, encoding="utf-8")) if source_body_pr is not None else ET.Element(f"{{{DML_NS}}}bodyPr") ) + source_bounds = _shape_bounds_emu(source_shape, None) + target_bounds = _shape_bounds_emu(source_shape, item.placeholder_bounds) + _normalize_placeholder_body_properties( + body_pr, + source_bounds, + target_bounds, + ) + tx_body.append(body_pr) list_style = ( ET.fromstring(ET.tostring(source_lst_style, encoding="utf-8")) if source_lst_style is not None @@ -2105,9 +2332,22 @@ def _placeholder_text_body( tx_body.append(list_style) paragraph = ET.SubElement(tx_body, f"{{{DML_NS}}}p") + source_paragraph_props = ( + source_tx_body.find(f"{{{DML_NS}}}p/{{{DML_NS}}}pPr") + if source_tx_body is not None + else None + ) + paragraph_props = ( + ET.fromstring(ET.tostring(source_paragraph_props, encoding="utf-8")) + if source_paragraph_props is not None + else None + ) if item.placeholder in {"body", "subtitle"}: - paragraph_props = ET.SubElement(paragraph, f"{{{DML_NS}}}pPr") + if paragraph_props is None: + paragraph_props = ET.Element(f"{{{DML_NS}}}pPr") _set_no_bullet_paragraph_properties(paragraph_props) + if paragraph_props is not None: + paragraph.append(paragraph_props) if item.placeholder in {"slide-number", "date"}: field_type = ( "slidenum" @@ -2392,8 +2632,14 @@ def _apply_explicit_layout_structure( conversion_traces: list[dict[str, Any]] | None, theme_font_spec: ThemeFontSpec | None, *, + use_layout_placeholder_frames: bool = False, verbose: bool = False, -) -> tuple[dict[str, str | None], dict[str, tuple[str, ...]]]: +) -> tuple[ + dict[str, str | None], + dict[str, tuple[str, ...]], + dict[str, str], + dict[str, str], +]: """Materialize explicit SVG master/layout/placeholder metadata into OOXML.""" master_parts_by_key = _assign_structured_masters( extract_dir, @@ -2437,6 +2683,7 @@ def _apply_explicit_layout_structure( placeholder_count = 0 layout_shape_count = 0 created_layout_parts: set[str] = set() + layout_parts_by_key: dict[str, str] = {} for layout_key, layout_specs in specs_by_layout.items(): layout_states = [states_by_slide[spec.slide_num] for spec in layout_specs] master_parts = { @@ -2463,6 +2710,7 @@ def _apply_explicit_layout_structure( layout_path = extract_dir / layout_part layout_rels_path = _relationships_path_for_part(extract_dir, layout_part) created_layout_parts.add(layout_part) + layout_parts_by_key[layout_key] = layout_part placeholder_bindings = { binding.element.element_id: binding @@ -2519,6 +2767,8 @@ def _apply_explicit_layout_structure( assigned_idx, theme_font_spec=theme_font_spec, ) + if use_layout_placeholder_frames: + _apply_layout_frame_to_placeholder_carrier(shape, item) _set_shape_name( shape, f"{item.element_id} Placeholder Carrier", @@ -2576,7 +2826,12 @@ def _apply_explicit_layout_structure( f"{len(slide_backgrounds)} slide background(s), " f"{placeholder_count} placeholder definition(s)" ) - return expected_backgrounds, expected_shape_rosters + return ( + expected_backgrounds, + expected_shape_rosters, + layout_parts_by_key, + master_parts_by_key, + ) def _apply_preserved_structure( @@ -3015,6 +3270,132 @@ def _remove_content_type_override(content_types_path: Path, part_name: str) -> N content_types_path.write_text(new_content, encoding="utf-8") +def _remove_trailing_layout_definition_slides( + extract_dir: Path, + public_slide_count: int, + total_slide_count: int, +) -> int: + """Remove internal carrier slides after their Layouts are registered.""" + if total_slide_count <= public_slide_count: + return 0 + presentation_part = "ppt/presentation.xml" + presentation_path = extract_dir / presentation_part + presentation_rels = _relationships_path_for_part( + extract_dir, + presentation_part, + ) + tree = ET.parse(presentation_path) + root = tree.getroot() + slide_list = root.find(f"{{{PML_NS}}}sldIdLst") + if slide_list is None: + raise RuntimeError("presentation.xml has no p:sldIdLst") + entries_by_rel_id = { + entry.get(f"{{{REL_NS}}}id", ""): entry + for entry in slide_list.findall(f"{{{PML_NS}}}sldId") + } + relationships = _read_relationships(presentation_rels) + content_types_path = extract_dir / "[Content_Types].xml" + removed = 0 + for slide_num in range(public_slide_count + 1, total_slide_count + 1): + slide_part = f"ppt/slides/slide{slide_num}.xml" + rel_ids = [ + rel_id + for rel_id, attrs in relationships.items() + if attrs.get("Type") == SLIDE_REL_TYPE + and _resolve_package_target( + presentation_part, + attrs.get("Target", ""), + ) == slide_part + ] + if len(rel_ids) != 1: + raise RuntimeError( + f"Internal Layout carrier {slide_part} must have exactly one " + "Presentation relationship" + ) + rel_id = rel_ids[0] + entry = entries_by_rel_id.get(rel_id) + if entry is None: + raise RuntimeError( + f"presentation.xml has no p:sldId entry for {slide_part}" + ) + slide_list.remove(entry) + _remove_relationship(presentation_rels, rel_id) + slide_path = extract_dir / slide_part + slide_rels = _relationships_path_for_part(extract_dir, slide_part) + if not slide_path.is_file() or not slide_rels.is_file(): + raise RuntimeError( + f"Internal Layout carrier package parts are incomplete: {slide_part}" + ) + slide_path.unlink() + slide_rels.unlink() + _remove_content_type_override(content_types_path, slide_part) + removed += 1 + _write_xml_tree(presentation_path, tree) + return removed + + +def _prune_unreferenced_definition_payload_parts(extract_dir: Path) -> int: + """Remove generated native/media payload left by deleted carrier slides. + + Definition-only SVGs are first converted as ordinary slides so their + reusable structure can be promoted. Removing those internal slides may + leave chart, workbook, or media parts with no remaining relationship. Run + an iterative incoming-reference sweep so chart-owned workbooks/styles are + removed after their orphan chart part and relationship sidecar disappear. + """ + candidate_prefixes = ( + "ppt/charts/", + "ppt/embeddings/", + "ppt/media/", + ) + content_types_path = extract_dir / "[Content_Types].xml" + removed = 0 + while True: + referenced_parts: set[str] = set() + for rels_path in extract_dir.rglob("*.rels"): + rels_rel = rels_path.relative_to(extract_dir).as_posix() + try: + root = ET.parse(rels_path).getroot() + except ET.ParseError as exc: + raise RuntimeError( + f"Invalid relationships XML while pruning {rels_rel}: {exc}" + ) from exc + for elem in root: + attrs = _relationship_attrs(elem) + if attrs.get("TargetMode", "").lower() == "external": + continue + target = attrs.get("Target") + if not target: + continue + resolved = _resolve_internal_opc_target(rels_rel, target) + if resolved is not None: + referenced_parts.add(resolved) + + orphan_paths: list[tuple[Path, str]] = [] + for path in extract_dir.rglob("*"): + if not path.is_file(): + continue + part_name = path.relative_to(extract_dir).as_posix() + if "/_rels/" in part_name: + continue + if not part_name.startswith(candidate_prefixes): + continue + canonical = _canonical_opc_part_path(part_name) + if canonical is not None and canonical not in referenced_parts: + orphan_paths.append((path, part_name)) + if not orphan_paths: + break + + for path, part_name in orphan_paths: + rels_path = _relationships_path_for_part(extract_dir, part_name) + if rels_path.is_file(): + rels_path.unlink() + path.unlink() + _remove_content_type_override(content_types_path, part_name) + removed += 1 + return removed + + def _prune_unused_slide_layouts( extract_dir: Path, structure: PptxStructureContext, @@ -3083,6 +3464,201 @@ def _prune_unused_slide_layouts( return pruned +def _flat_structure_name(value: str | None) -> str: + """Return one compact package identity for a free-design deck.""" + normalized = " ".join((value or "").split()).strip() + return (normalized or "Free Design")[:120] + + +def _flat_placeholder_type(shape: ET.Element) -> str | None: + """Return one system placeholder type carried by a top-level shape.""" + if shape.tag != f"{{{PML_NS}}}sp": + return None + placeholder = shape.find( + f"{{{PML_NS}}}nvSpPr/{{{PML_NS}}}nvPr/{{{PML_NS}}}ph" + ) + return placeholder.get("type") if placeholder is not None else None + + +def _clean_flat_structure_part( + part_path: Path, + name: str, + *, + is_layout: bool, +) -> tuple[int, tuple[str, ...]]: + """Keep only standard footer hooks in one project-owned flat shell.""" + try: + tree = ET.parse(part_path) + except (OSError, ET.ParseError) as exc: + raise RuntimeError( + f"Cannot parse flat structure part {part_path}: {exc}" + ) from exc + root = tree.getroot() + common_slide = root.find(f"{{{PML_NS}}}cSld") + if common_slide is None: + raise RuntimeError(f"Flat structure part has no p:cSld: {part_path}") + shape_tree = common_slide.find(f"{{{PML_NS}}}spTree") + if shape_tree is None: + raise RuntimeError(f"Flat structure part has no p:spTree: {part_path}") + + removed = 0 + retained: list[str] = [] + for child in list(shape_tree): + if child.tag not in _TOP_LEVEL_SHAPE_TAGS: + continue + placeholder_type = _flat_placeholder_type(child) + if placeholder_type in _FLAT_SYSTEM_PLACEHOLDER_TYPES: + retained.append(placeholder_type) + continue + shape_tree.remove(child) + removed += 1 + for parent in (common_slide, root): + for extension_list in parent.findall(f"{{{PML_NS}}}extLst"): + parent.remove(extension_list) + + common_slide.set("name", name) + if is_layout: + root.set("type", "blank") + root.set("preserve", "1") + _write_xml_tree(part_path, tree) + return removed, tuple(retained) + + +def _name_flat_themes(extract_dir: Path, name: str) -> int: + """Replace stock Office theme identities with the current deck identity.""" + theme_paths = sorted((extract_dir / "ppt" / "theme").glob("theme*.xml")) + if not theme_paths: + raise RuntimeError("Flat PPTX package has no theme part") + for theme_path in theme_paths: + try: + tree = ET.parse(theme_path) + except (OSError, ET.ParseError) as exc: + raise RuntimeError( + f"Cannot parse flat theme {theme_path}: {exc}" + ) from exc + root = tree.getroot() + root.set("name", name) + for tag in ("clrScheme", "fontScheme", "fmtScheme"): + scheme = root.find(f".//{{{DML_NS}}}{tag}") + if scheme is not None: + scheme.set("name", name) + _write_xml_tree(theme_path, tree) + return len(theme_paths) + + +def _prepare_flat_structure( + extract_dir: Path, + structure: PptxStructureContext, + slide_count: int, + master_text_style_spec: MasterTextStyleSpec | None, + structure_name: str | None, + *, + verbose: bool = False, +) -> None: + """Materialize one clean current-deck Master and Blank Layout for flat export.""" + pruned = _prune_unused_slide_layouts( + extract_dir, + structure, + slide_count, + verbose=False, + ) + live_structure = _read_slide_layout_targets(extract_dir, slide_count) + layout_parts = { + _resolve_package_target( + f"ppt/slides/slide{slide_num}.xml", + live_structure.slide_layout_target(slide_num), + ) + for slide_num in range(1, slide_count + 1) + } + master_parts = set(live_structure.slide_master_parts.values()) + physical_layouts = { + str(path.relative_to(extract_dir)).replace("\\", "/") + for path in (extract_dir / "ppt" / "slideLayouts").glob("slideLayout*.xml") + } + physical_masters = { + str(path.relative_to(extract_dir)).replace("\\", "/") + for path in (extract_dir / "ppt" / "slideMasters").glob("slideMaster*.xml") + } + if len(layout_parts) != 1 or layout_parts != physical_layouts: + raise RuntimeError( + "Flat export must retain exactly one slide-referenced Blank Layout" + ) + if len(master_parts) != 1 or master_parts != physical_masters: + raise RuntimeError( + "Flat export must retain exactly one slide-referenced Master" + ) + + identity = _flat_structure_name(structure_name) + theme_name = identity + master_name = f"{identity} — Master" + layout_name = f"{identity} — Blank" + master_path = extract_dir / next(iter(master_parts)) + layout_path = extract_dir / next(iter(layout_parts)) + removed_master_shapes, retained_master_placeholders = _clean_flat_structure_part( + master_path, + master_name, + is_layout=False, + ) + removed_layout_shapes, retained_layout_placeholders = _clean_flat_structure_part( + layout_path, + layout_name, + is_layout=True, + ) + theme_count = _name_flat_themes(extract_dir, theme_name) + master_count = ( + apply_master_text_style_spec(extract_dir, master_text_style_spec) + if master_text_style_spec is not None + else 0 + ) + + for part_path, expected_name, expected_layout in ( + (master_path, master_name, False), + (layout_path, layout_name, True), + ): + root = ET.parse(part_path).getroot() + common_slide = root.find(f"{{{PML_NS}}}cSld") + if common_slide is None or common_slide.get("name") != expected_name: + raise RuntimeError( + f"Flat structure identity read-back failed: {part_path}" + ) + shape_tree = common_slide.find(f"{{{PML_NS}}}spTree") + if shape_tree is None: + raise RuntimeError(f"Flat structure shell has no shape tree: {part_path}") + actual_placeholder_types = tuple( + sorted( + _flat_placeholder_type(child) or "" + for child in shape_tree + if child.tag in _TOP_LEVEL_SHAPE_TAGS + ) + ) + expected_placeholder_types = tuple( + sorted(_FLAT_SYSTEM_PLACEHOLDER_TYPES) + ) + if actual_placeholder_types != expected_placeholder_types: + raise RuntimeError( + "Flat structure shell must retain only one each of the date, " + f"footer, and slide-number hooks: {part_path}" + ) + if expected_layout and root.get("type") != "blank": + raise RuntimeError(f"Flat layout is not typed as Blank: {part_path}") + + if verbose: + print( + " Flat structure: project-owned Master + Blank Layout " + f"({pruned} stock layout(s), " + f"{removed_master_shapes + removed_layout_shapes} stock content " + "shape(s) removed, " + f"{len(retained_master_placeholders) + len(retained_layout_placeholders)} " + "system footer hook(s) retained)" + ) + text_style_status = ( + f"{master_count} master text style(s)" + if master_text_style_spec is not None + else "stock text defaults retained (diagnostic caller)" + ) + print(f" Flat theme: {theme_count} theme part(s), {text_style_status}") + + def _append_relationship( rels_path: Path, rel_type: str, @@ -3874,19 +4450,25 @@ def create_pptx_with_native_svg( native_objects: bool = False, conversion_trace_path: Path | None = None, doc_metadata: dict[str, Any] | None = None, + structure_name: str | None = None, pptx_structure: str = "structured", + use_layout_placeholder_frames: bool = False, native_structure_contract: NativeStructureContract | None = None, theme_font_spec: ThemeFontSpec | None = None, master_text_style_spec: MasterTextStyleSpec | None = None, theme_color_spec: ThemeColorSpec | None = None, structured_baseline: bool = False, baseline_layout_specs: list[TemplateSlideSpec] | None = None, + layout_definition_files: list[Path] | None = None, ) -> bool: """Create a PPTX file with native DrawingML shapes. Args: svg_files: List of SVG files. output_path: Output PPTX path. + layout_definition_files: Optional structured SVG prototypes for Layouts + that no generated page uses. They are converted on internal carrier + slides, registered, and removed before the package is published. canvas_format: Canvas format key. verbose: Whether to output detailed information. transition: Transition effect name. @@ -3917,6 +4499,8 @@ def create_pptx_with_native_svg( native_objects: Convert explicit ``data-pptx-native`` table/chart markers to native PowerPoint objects. Default off. conversion_trace_path: Optional JSON path for native conversion diagnostics. + structure_name: Current deck identity used to name a flat Master, Layout, + and theme. pptx_structure: PPTX structure strategy. ``baseline`` promotes safe shared native backgrounds and leading chrome to slide masters, then extracts semantic page-role layout families and exact @@ -3924,35 +4508,72 @@ def create_pptx_with_native_svg( SVGs retain filename/id fallback; ``structured`` consumes explicit SVG master/layout/placeholder metadata; ``preserve`` reuses an imported source PPTX package; - ``flat`` keeps generated structure slide-local. + ``flat`` keeps generated content Slide-local and builds one clean + project-owned Master/Blank-Layout shell. + use_layout_placeholder_frames: In structured template-review decks, size + each Slide placeholder carrier to its reusable Layout bounds instead + of the tight SVG content frame. Default off for generated decks. native_structure_contract: Validated source package contract for ``preserve`` mode. - theme_font_spec: Locked project major/minor fonts for baseline/structured - theme inheritance. Preserve and flat modes ignore this value. + theme_font_spec: Locked project major/minor fonts for flat/structured + release-theme inheritance. Direct diagnostic flat callers may omit it. master_text_style_spec: Required locked title/body sizes for structured - slide-master text styles. Other structure - routes ignore this value. + and release flat slide-master text styles. Direct diagnostic flat + callers may omit it; other routes ignore this value. theme_color_spec: Locked project color scheme for context-aware - baseline/structured theme inheritance. Preserve and flat modes - ignore this value. + flat/structured theme inheritance. Preserve mode ignores this value. structured_baseline: Obsolete compatibility argument; must remain false. baseline_layout_specs: Obsolete compatibility argument; must remain None. Returns: Whether all slides were successfully created. """ + public_svg_files = list(svg_files) + definition_svg_files = list(layout_definition_files or []) + if definition_svg_files and pptx_structure != "structured": + raise ValueError( + "layout_definition_files requires pptx_structure='structured'" + ) + public_paths = {path.resolve() for path in public_svg_files} + seen_definition_paths: set[Path] = set() + for path in definition_svg_files: + resolved = path.resolve() + if not path.is_file(): + raise ValueError(f"Layout definition SVG does not exist: {path}") + if resolved in public_paths: + raise ValueError( + f"Layout definition SVG is already a generated page: {path}" + ) + if resolved in seen_definition_paths: + raise ValueError(f"Layout definition SVG is repeated: {path}") + seen_definition_paths.add(resolved) + public_slide_count = len(public_svg_files) + svg_files = public_svg_files + definition_svg_files + total_slide_count = len(svg_files) + if not use_native_shapes: raise ValueError( "SVG-image PPTX export is no longer supported; use svg_final/ " "directly for preview and native DrawingML PPTX for delivery" ) - if not svg_files: + if not public_svg_files: print("Error: No SVG files found") return False use_compat_mode = False if pptx_structure not in {"baseline", "structured", "preserve", "flat"}: raise ValueError(f"Unsupported pptx_structure: {pptx_structure}") + if pptx_structure == "flat": + flat_errors = flat_structure_metadata_errors(public_svg_files) + if flat_errors: + details = "\n".join(f" - {error}" for error in flat_errors) + raise TemplateStructureError( + "Flat PPTX structure validation failed:\n" + details + ) + if use_layout_placeholder_frames and pptx_structure != "structured": + raise ValueError( + "use_layout_placeholder_frames requires pptx_structure='structured'" + ) if structured_baseline: raise ValueError( "structured_baseline is obsolete; use pptx_structure='structured'" @@ -3968,6 +4589,7 @@ def create_pptx_with_native_svg( ) if use_native_shapes and pptx_structure == "structured": template_specs = parse_template_slides(svg_files) + public_template_specs = template_specs[:public_slide_count] elif use_native_shapes and pptx_structure == "preserve": if native_structure_contract is None: raise TemplateStructureError( @@ -3976,12 +4598,16 @@ def create_pptx_with_native_svg( template_specs = parse_preserve_slides(svg_files) for spec in template_specs: native_structure_contract.layout(spec.layout_key) + public_template_specs = template_specs else: template_specs = None + public_template_specs = None template_background_expectations: dict[str, str | None] | None = None template_shape_roster_expectations: ( dict[str, tuple[str, ...]] | None ) = None + template_layout_parts_by_key: dict[str, str] | None = None + template_master_parts_by_key: dict[str, str] | None = None if template_specs is not None and not native_objects: native_placeholders = sorted({ item.placeholder @@ -4030,7 +4656,12 @@ def create_pptx_with_native_svg( if verbose: print(f" Slide dimensions: {pixel_width} x {pixel_height} px") - print(f" SVG file count: {len(svg_files)}") + print(f" SVG file count: {public_slide_count}") + if definition_svg_files: + print( + " Unused Layout definitions: " + f"{len(definition_svg_files)} internal prototype(s)" + ) if use_native_shapes: print(f" Mode: Native DrawingML shapes (directly editable)") print( @@ -4105,14 +4736,16 @@ def create_pptx_with_native_svg( _clear_preserved_slide_collections(extract_dir) active_theme_font_spec = ( theme_font_spec - if use_native_shapes and pptx_structure in {"baseline", "structured"} + if use_native_shapes + and pptx_structure in {"baseline", "flat", "structured"} else None ) if active_theme_font_spec is not None: apply_theme_font_spec(extract_dir, active_theme_font_spec) active_theme_color_spec = ( theme_color_spec - if use_native_shapes and pptx_structure in {"baseline", "structured"} + if use_native_shapes + and pptx_structure in {"baseline", "flat", "structured"} else None ) if active_theme_color_spec is not None: @@ -4170,6 +4803,7 @@ def create_pptx_with_native_svg( for i, svg_path in enumerate(svg_files, 1): slide_num = i + is_layout_definition = slide_num > public_slide_count expected_animation_targets: list[tuple[int, int, str, float]] = [] expected_animation_duration = animation_duration expected_animation_trigger = normalize_animation_trigger(animation_trigger) @@ -4177,29 +4811,44 @@ def create_pptx_with_native_svg( try: # ---- Native shapes mode ---- if use_native_shapes: - slide_cfg = _slide_config(animation_config, svg_path.stem) - slide_transition, slide_transition_duration, slide_auto_advance = ( - _slide_transition_settings( + slide_cfg = ( + {} + if is_layout_definition + else _slide_config(animation_config, svg_path.stem) + ) + if is_layout_definition: + slide_transition = None + slide_transition_duration = transition_duration + slide_auto_advance = None + slide_animation = None + slide_animation_duration = animation_duration + slide_animation_stagger = animation_stagger + slide_animation_trigger = animation_trigger + else: + ( + slide_transition, + slide_transition_duration, + slide_auto_advance, + ) = _slide_transition_settings( slide_cfg, transition, transition_duration, auto_advance, animation_cli_overrides, ) - ) - ( - slide_animation, - slide_animation_duration, - slide_animation_stagger, - slide_animation_trigger, - ) = _slide_animation_settings( - slide_cfg, - animation, - animation_duration, - animation_stagger, - animation_trigger, - animation_cli_overrides, - ) + ( + slide_animation, + slide_animation_duration, + slide_animation_stagger, + slide_animation_trigger, + ) = _slide_animation_settings( + slide_cfg, + animation, + animation_duration, + animation_stagger, + animation_trigger, + animation_cli_overrides, + ) groups_value = slide_cfg.get('groups', {}) if not isinstance(groups_value, dict): raise ValueError( @@ -4444,7 +5093,7 @@ def create_pptx_with_native_svg( # --- Process notes (shared between native and legacy mode) --- notes_content = '' - if enable_notes: + if enable_notes and not is_layout_definition: svg_stem = svg_path.stem notes_content = notes.get(svg_stem, '') if notes else '' notes_text = markdown_to_plain_text(notes_content) if notes_content else '' @@ -4475,7 +5124,11 @@ def create_pptx_with_native_svg( # --- Process narration audio (shared between native and legacy mode) --- svg_stem = svg_path.stem - audio_path = narration_audio.get(svg_stem) if narration_audio else None + audio_path = ( + narration_audio.get(svg_stem) + if narration_audio and not is_layout_definition + else None + ) if audio_path: slide_xml_path = extract_dir / 'ppt' / 'slides' / f'slide{slide_num}.xml' rels_path = extract_dir / 'ppt' / 'slides' / '_rels' / f'slide{slide_num}.xml.rels' @@ -4580,7 +5233,13 @@ def create_pptx_with_native_svg( has_notes = slide_num in notes_slides_created notes_str = " +notes" if has_notes else "" narration_str = " +narration" if slide_num in narration_slides_created else "" - print(f" [{i}/{len(svg_files)}] {svg_path.name}{mode_str}{notes_str}{narration_str}") + definition_str = ( + " [Layout definition]" if is_layout_definition else "" + ) + print( + f" [{i}/{len(svg_files)}] {svg_path.name}{mode_str}" + f"{notes_str}{narration_str}{definition_str}" + ) success_count += 1 @@ -4634,6 +5293,20 @@ def create_pptx_with_native_svg( verbose=verbose, ) + if ( + use_native_shapes + and pptx_structure == "flat" + and success_count == len(svg_files) + ): + _prepare_flat_structure( + extract_dir, + structure, + len(svg_files), + master_text_style_spec, + structure_name, + verbose=verbose, + ) + if ( use_native_shapes and pptx_structure == "structured" @@ -4653,12 +5326,15 @@ def create_pptx_with_native_svg( ( template_background_expectations, template_shape_roster_expectations, + template_layout_parts_by_key, + template_master_parts_by_key, ) = _apply_explicit_layout_structure( extract_dir, structure, template_specs, conversion_trace if conversion_trace is not None else structure_trace, active_theme_font_spec, + use_layout_placeholder_frames=use_layout_placeholder_frames, verbose=verbose, ) master_count = apply_master_text_style_spec( @@ -4670,7 +5346,9 @@ def create_pptx_with_native_svg( " Structured master text styles: " f"{master_count} master(s), " f"title {master_text_style_spec.title_hpt / 100:g}pt, " - f"body {master_text_style_spec.body_hpt / 100:g}pt" + "body levels " + f"{master_text_style_spec.body_levels_hpt[0] / 100:g}–" + f"{master_text_style_spec.body_levels_hpt[-1] / 100:g}pt" ) _prune_unused_slide_layouts( extract_dir, @@ -4703,6 +5381,33 @@ def create_pptx_with_native_svg( verbose=verbose, ) + if ( + use_native_shapes + and pptx_structure == "structured" + and definition_svg_files + and success_count == total_slide_count + ): + removed = _remove_trailing_layout_definition_slides( + extract_dir, + public_slide_count, + total_slide_count, + ) + pruned_payload_parts = _prune_unreferenced_definition_payload_parts( + extract_dir + ) + for slide_num in range(public_slide_count + 1, total_slide_count + 1): + slide_part = f"ppt/slides/slide{slide_num}.xml" + if template_background_expectations is not None: + template_background_expectations.pop(slide_part, None) + if template_shape_roster_expectations is not None: + template_shape_roster_expectations.pop(slide_part, None) + if verbose: + print( + " Layout definition carriers: " + f"removed {removed} internal slide(s), pruned " + f"{pruned_payload_parts} orphan payload part(s)" + ) + # Update [Content_Types].xml content_types_path = extract_dir / '[Content_Types].xml' with open(content_types_path, 'r', encoding='utf-8') as f: @@ -4782,7 +5487,7 @@ def create_pptx_with_native_svg( # author, 2013 dates, "generated using python-pptx", Slides=0) with # accurate, tool-neutral document properties. pres_format = _presentation_format(width_emu, height_emu) - _stamp_docprops(extract_dir, len(svg_files), pres_format, doc_metadata) + _stamp_docprops(extract_dir, public_slide_count, pres_format, doc_metadata) # Repackage PPTX to a temporary file first. The public output path is # replaced only after every slide and relationship has succeeded. @@ -4797,14 +5502,17 @@ def create_pptx_with_native_svg( and pptx_structure == "structured" and success_count == len(svg_files) ): - if template_specs is None: + if template_specs is None or public_template_specs is None: raise TemplateStructureError( "Explicit Layout metadata was not parsed before validation" ) try: validate_pptx_template_package( temp_output_path, - template_specs, + public_template_specs, + layout_specs=template_specs, + expected_layout_parts=template_layout_parts_by_key, + expected_master_parts=template_master_parts_by_key, expected_backgrounds=template_background_expectations, expected_shape_rosters=template_shape_roster_expectations, ) @@ -4837,8 +5545,12 @@ def create_pptx_with_native_svg( conversion_trace_path.parent.mkdir(parents=True, exist_ok=True) payload = { 'output': str(output_path), - 'slide_count': len(svg_files), - 'slides': conversion_trace, + 'slide_count': public_slide_count, + 'slides': [ + entry + for entry in conversion_trace + if int(entry.get('slide_num', 0)) <= public_slide_count + ], } conversion_trace_path.write_text( json.dumps(payload, ensure_ascii=False, indent=2), @@ -4852,7 +5564,10 @@ def create_pptx_with_native_svg( print(f" [warn] {warning}") if conversion_trace_path and conversion_trace is not None: print(f" Trace: {conversion_trace_path}") - print(f" Succeeded: {success_count}, Failed: {len(svg_files) - success_count}") + print( + f" Slides: {public_slide_count}; " + f"Layout definitions: {len(definition_svg_files)}" + ) if use_compat_mode and has_any_image: print(f" Mode: Office compatibility mode (supports all Office versions)") if PNG_RENDERER == 'svglib' and renderer_hint: diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/pptx_package/cli.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/pptx_package/cli.py index 836261e7..c08ba1df 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/pptx_package/cli.py +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/pptx_package/cli.py @@ -51,6 +51,7 @@ from .template_structure import ( TemplateStructureError, load_pptx_structure_lock, parse_template_slides, + structured_layout_definition_files, template_lock_errors, template_prototype_errors, ) @@ -78,6 +79,7 @@ _LEGACY_PPTX_STRUCTURE_MODES = frozenset({ 'preserve', 'template', }) +_RELEASE_PPTX_STRUCTURE_MODES = frozenset({'flat', 'structured'}) def _declared_pptx_structure_mode(project_path: Path) -> str | None: @@ -98,14 +100,15 @@ def _print_structure_migration_error(mode: str | None) -> None: """Explain how a legacy or absent SVG structure contract is restored.""" label = repr(mode) if mode else 'missing (legacy implicit baseline)' print( - "Error: release SVG export requires spec_lock.md " - "pptx_structure.mode: structured; found " + label + ".", + "Error: release SVG export requires an explicit spec_lock.md " + "pptx_structure.mode: flat (free design / brand-only) or structured " + "(deck/layout template); found " + label + ".", file=sys.stderr, ) print( - " Restore explicit Master/Layout metadata first by following " - "skills/ppt-master/workflows/restore-pptx-structure.md, then rerun " - "the quality gate and export.", + " New free-design and brand-only projects use mode: flat. Restore " + "legacy template/structured metadata by following skills/ppt-master/" + "workflows/restore-pptx-structure.md before export.", file=sys.stderr, ) @@ -320,12 +323,12 @@ Recorded narration: ], default=None, help=( - 'PPTX structure strategy for native export. Release export requires ' - 'spec_lock.md pptx_structure.mode: structured and complete explicit ' - 'Master/Layout metadata in every SVG. flat is an explicit diagnostic ' - 'override that leaves all generated objects slide-local. baseline, ' - 'template, preserve, and generated are accepted only so legacy ' - 'invocations can receive a targeted migration error.' + 'PPTX structure strategy for native export. Omitting this flag reads ' + 'spec_lock.md: flat is the free-design/brand-only release mode and ' + 'builds one clean project-owned Master plus Blank Layout while keeping ' + 'all SVG objects slide-local; structured is the deck/layout-template ' + 'mode and requires complete explicit metadata. baseline, template, ' + 'preserve, and generated are accepted only to report a migration error.' ), ) parser.add_argument('--no-image-optimize', action='store_true', @@ -419,24 +422,27 @@ Recorded narration: _print_structure_migration_error(pptx_structure) return 1 if pptx_structure is None: - if declared_structure_mode != 'structured': + if declared_structure_mode not in _RELEASE_PPTX_STRUCTURE_MODES: _print_structure_migration_error(declared_structure_mode) return 1 - pptx_structure = 'structured' + pptx_structure = declared_structure_mode elif pptx_structure == 'structured' and declared_structure_mode != 'structured': _print_structure_migration_error(declared_structure_mode) return 1 - if pptx_structure == 'structured': + if ( + pptx_structure in _RELEASE_PPTX_STRUCTURE_MODES + and declared_structure_mode == pptx_structure + ): try: structure_lock = load_pptx_structure_lock(project_path) except TemplateStructureError as exc: print(f"Error: {exc}", file=sys.stderr) return 1 - if structure_lock is None or structure_lock.mode != 'structured': + if structure_lock is None or structure_lock.mode != pptx_structure: print( "Error: spec_lock.md must contain one complete " - "pptx_structure.mode: structured contract", + f"pptx_structure.mode: {pptx_structure} contract", file=sys.stderr, ) return 1 @@ -444,7 +450,7 @@ Recorded narration: theme_font_spec = None master_text_style_spec = None theme_color_spec = None - if pptx_structure == 'structured': + if pptx_structure in {'flat', 'structured'}: try: theme_font_spec = load_theme_font_spec(project_path) master_text_style_spec = load_master_text_style_spec(project_path) @@ -452,6 +458,21 @@ Recorded narration: except (ThemeFontError, ThemeColorError) as exc: print(f"Error: {exc}", file=sys.stderr) return 1 + missing_theme_fields = [] + if theme_font_spec is None: + missing_theme_fields.append( + 'typography font_family/title_family/body_family' + ) + if theme_color_spec is None: + missing_theme_fields.append('colors') + if missing_theme_fields: + print( + f"Error: {pptx_structure} export requires a current-project " + "theme contract in spec_lock.md; missing: " + + ", ".join(missing_theme_fields), + file=sys.stderr, + ) + return 1 if args.image_max_dimension < 1: print("Error: --image-max-dimension must be >= 1", file=sys.stderr) return 1 @@ -487,6 +508,7 @@ Recorded narration: # parameters are removed. Structured export never activates either path. structured_baseline = False baseline_layout_specs = None + layout_definition_files: list[Path] = [] if pptx_structure == 'structured' and structure_lock is not None: try: template_specs = parse_template_slides(native_files) @@ -499,6 +521,14 @@ Recorded narration: for message in lock_errors: print(f" {message}", file=sys.stderr) return 1 + try: + layout_definition_files = structured_layout_definition_files( + template_specs, + structure_lock, + ) + except TemplateStructureError as exc: + print(f"Error: {exc}", file=sys.stderr) + return 1 prototype_errors = template_prototype_errors( template_specs, structure_lock, @@ -847,9 +877,16 @@ Recorded narration: else: print(" [warn] metadata.json ignored (top level is not an object)", file=sys.stderr) + structure_name = project_name + if isinstance(doc_metadata, dict): + metadata_title = doc_metadata.get('title') + if isinstance(metadata_title, str) and metadata_title.strip(): + structure_name = metadata_title + shared_kwargs = dict( canvas_format=canvas_format, doc_metadata=doc_metadata, + structure_name=structure_name, verbose=verbose, transition=transition, transition_duration=transition_duration, @@ -875,6 +912,7 @@ Recorded narration: pptx_structure=pptx_structure, structured_baseline=structured_baseline, baseline_layout_specs=baseline_layout_specs, + layout_definition_files=layout_definition_files, native_structure_contract=native_structure_contract, theme_font_spec=theme_font_spec, master_text_style_spec=master_text_style_spec, diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/pptx_package/template_structure.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/pptx_package/template_structure.py index a9b9295d..3bfd33e7 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/pptx_package/template_structure.py +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/pptx_package/template_structure.py @@ -47,6 +47,9 @@ _STRUCTURE_ATTRS = frozenset({ "data-pptx-placeholder-idx", "data-pptx-editable", }) +_FLAT_FORBIDDEN_STRUCTURE_ATTRS = frozenset( + _STRUCTURE_ATTRS - {"data-pptx-editable"} +) _LAYERS = frozenset({"master", "layout", "slide"}) _PLACEHOLDERS = frozenset({ "title", @@ -150,7 +153,7 @@ class TemplateStructureError(RuntimeError): @dataclass(frozen=True) class PptxLayoutReference: - """One spec_lock page-to-PowerPoint-layout declaration.""" + """One spec_lock page-to-PowerPoint-layout assignment.""" slide_num: int layout_key: str @@ -158,6 +161,17 @@ class PptxLayoutReference: master_key: str | None = None +@dataclass(frozen=True) +class PptxLayoutDefinition: + """One reusable PowerPoint Layout declared by a structured project lock.""" + + layout_key: str + master_key: str + layout_name: str + prototype_slide_num: int | None = None + prototype_svg_path: Path | None = None + + @dataclass(frozen=True) class PptxMasterReference: """One named Master declared by the structured project lock.""" @@ -183,6 +197,7 @@ class PptxStructureLock: mode: str template_adherence: str | None = None masters: tuple[PptxMasterReference, ...] = () + layout_definitions: tuple[PptxLayoutDefinition, ...] = () layouts: tuple[PptxLayoutReference, ...] = () prototypes: tuple[PptxPrototypeReference, ...] = () source_template: Path | None = None @@ -480,6 +495,37 @@ def _template_replication_mode(template_dir: Path) -> str | None: return None +def _template_svg_path( + template_dir: Path, + raw_basename: str, + context: str, +) -> tuple[str, Path]: + """Resolve one flat template SVG basename inside the project workspace.""" + basename = ( + raw_basename[:-4] + if raw_basename.lower().endswith(".svg") + else raw_basename + ) + if ( + not basename + or basename in {".", ".."} + or "/" in basename + or "\\" in basename + or any(ord(char) < 0x20 for char in basename) + ): + raise TemplateStructureError( + f"spec_lock.md {context} has invalid template SVG basename " + f"{raw_basename!r}" + ) + svg_path = (template_dir / f"{basename}.svg").resolve() + if svg_path.parent != template_dir or not svg_path.is_file(): + raise TemplateStructureError( + f"spec_lock.md {context} references missing template SVG " + f"templates/{basename}.svg" + ) + return basename, svg_path + + def load_pptx_structure_lock(project_path: Path) -> PptxStructureLock | None: """Load optional native-structure sections from spec_lock.md.""" lock_path = project_path / "spec_lock.md" @@ -502,6 +548,7 @@ def load_pptx_structure_lock(project_path: Path) -> PptxStructureLock | None: "pptx_structure", "pptx_masters", "pptx_layouts", + "page_pptx_layouts", "page_layouts", }: continue @@ -512,19 +559,23 @@ def load_pptx_structure_lock(project_path: Path) -> PptxStructureLock | None: structure_rows = sections.get("pptx_structure", []) master_rows = sections.get("pptx_masters", []) layout_rows = sections.get("pptx_layouts", []) + page_layout_rows = sections.get("page_pptx_layouts", []) prototype_rows = sections.get("page_layouts", []) structure_section_present = "pptx_structure" in sections master_section_present = "pptx_masters" in sections layout_section_present = "pptx_layouts" in sections + page_layout_section_present = "page_pptx_layouts" in sections prototype_section_present = "page_layouts" in sections if ( not structure_rows and not master_rows and not layout_rows + and not page_layout_rows and not prototype_rows and not structure_section_present and not master_section_present and not layout_section_present + and not page_layout_section_present and not prototype_section_present ): return None @@ -640,9 +691,9 @@ def load_pptx_structure_lock(project_path: Path) -> PptxStructureLock | None: seen_prototype_slides: set[int] = set() template_dir = (project_path / "templates").resolve() template_replication_mode = _template_replication_mode(template_dir) - if mode != "structured" and prototype_rows: + if mode != "structured" and prototype_section_present: raise TemplateStructureError( - "spec_lock.md page_layouts is allowed only when pptx_structure.mode " + "spec_lock.md page_layouts section is allowed only when pptx_structure.mode " "is structured" ) for page_key, raw_value in prototype_rows: @@ -658,28 +709,11 @@ def load_pptx_structure_lock(project_path: Path) -> PptxStructureLock | None: ) seen_prototype_slides.add(slide_num) raw_basename = raw_value.strip() - basename = ( - raw_basename[:-4] - if raw_basename.lower().endswith(".svg") - else raw_basename + basename, svg_path = _template_svg_path( + template_dir, + raw_basename, + f"page_layouts P{slide_num:02d}", ) - if ( - not basename - or basename in {".", ".."} - or "/" in basename - or "\\" in basename - or any(ord(char) < 0x20 for char in basename) - ): - raise TemplateStructureError( - f"spec_lock.md P{slide_num:02d} has invalid template SVG basename " - f"{raw_basename!r}" - ) - svg_path = (template_dir / f"{basename}.svg").resolve() - if svg_path.parent != template_dir or not svg_path.is_file(): - raise TemplateStructureError( - f"spec_lock.md P{slide_num:02d} references missing template SVG " - f"templates/{basename}.svg" - ) prototypes.append(PptxPrototypeReference( slide_num=slide_num, template_basename=basename, @@ -696,98 +730,164 @@ def load_pptx_structure_lock(project_path: Path) -> PptxStructureLock | None: "spec_lock.md page_layouts requires template_adherence: strict or adaptive" ) + layout_definitions: list[PptxLayoutDefinition] = [] references: list[PptxLayoutReference] = [] - seen_slides: set[int] = set() - for page_key, raw_value in layout_rows: - page_match = _LOCK_PAGE_RE.fullmatch(page_key) - if not page_match or int(page_match.group(1)) <= 0: + if mode == "structured": + if not layout_rows: raise TemplateStructureError( - f"spec_lock.md pptx_layouts key {page_key!r} must be P" + "spec_lock.md structured mode requires a non-empty " + "pptx_layouts definition section" ) - slide_num = int(page_match.group(1)) - if slide_num in seen_slides: - raise TemplateStructureError( - f"spec_lock.md pptx_layouts repeats page P{slide_num:02d}" - ) - seen_slides.add(slide_num) - parts = [part.strip() for part in raw_value.split("|")] - master_key: str | None = None - if mode == "structured": + seen_layout_keys: set[str] = set() + for layout_key, raw_value in layout_rows: + if not _LAYOUT_KEY_RE.fullmatch(layout_key): + raise TemplateStructureError( + f"spec_lock.md has invalid Layout key {layout_key!r}; use 1-64 " + "ASCII letters, digits, dots, underscores, or hyphens" + ) + if layout_key in seen_layout_keys: + raise TemplateStructureError( + f"spec_lock.md pptx_layouts repeats Layout key {layout_key!r}" + ) + seen_layout_keys.add(layout_key) + parts = [part.strip() for part in raw_value.split("|")] if len(parts) != 3 or not all(parts): raise TemplateStructureError( - f"spec_lock.md P{slide_num:02d} structured mapping must be " - "' | | '" + f"spec_lock.md Layout {layout_key!r} must be " + "' | | " + " or template:>'" ) - master_key, layout_key, layout_name = parts + master_key, layout_name, raw_source = parts if not _MASTER_KEY_RE.fullmatch(master_key): raise TemplateStructureError( - f"spec_lock.md P{slide_num:02d} has invalid Master key " + f"spec_lock.md Layout {layout_key!r} has invalid Master key " f"{master_key!r}" ) if master_key not in seen_master_keys: raise TemplateStructureError( - f"spec_lock.md P{slide_num:02d} references undeclared Master " - f"{master_key!r}" + f"spec_lock.md Layout {layout_key!r} references undeclared " + f"Master {master_key!r}" ) - else: + prototype_slide_num: int | None = None + prototype_svg_path: Path | None = None + page_match = _LOCK_PAGE_RE.fullmatch(raw_source) + if page_match and int(page_match.group(1)) > 0: + prototype_slide_num = int(page_match.group(1)) + elif raw_source.startswith("template:"): + raw_basename = raw_source.split(":", 1)[1].strip() + _basename, prototype_svg_path = _template_svg_path( + template_dir, + raw_basename, + f"pptx_layouts Layout {layout_key!r}", + ) + else: + raise TemplateStructureError( + f"spec_lock.md Layout {layout_key!r} prototype source must be " + "P or template:" + ) + layout_definitions.append(PptxLayoutDefinition( + layout_key=layout_key, + master_key=master_key, + layout_name=layout_name, + prototype_slide_num=prototype_slide_num, + prototype_svg_path=prototype_svg_path, + )) + + seen_slides: set[int] = set() + for page_key, raw_value in page_layout_rows: + page_match = _LOCK_PAGE_RE.fullmatch(page_key) + if not page_match or int(page_match.group(1)) <= 0: + raise TemplateStructureError( + f"spec_lock.md page_pptx_layouts key {page_key!r} must be P" + ) + slide_num = int(page_match.group(1)) + if slide_num in seen_slides: + raise TemplateStructureError( + "spec_lock.md page_pptx_layouts repeats page " + f"P{slide_num:02d}" + ) + seen_slides.add(slide_num) + layout_key = raw_value.strip() + if not _LAYOUT_KEY_RE.fullmatch(layout_key): + raise TemplateStructureError( + f"spec_lock.md P{slide_num:02d} has invalid Layout key " + f"{layout_key!r}" + ) + if layout_key not in seen_layout_keys: + raise TemplateStructureError( + f"spec_lock.md P{slide_num:02d} references undeclared Layout " + f"{layout_key!r}" + ) + references.append(PptxLayoutReference( + slide_num=slide_num, + layout_key=layout_key, + )) + if not references: + raise TemplateStructureError( + "spec_lock.md structured mode requires one page_pptx_layouts " + "assignment per generated page" + ) + unused_masters = sorted( + seen_master_keys - { + definition.master_key for definition in layout_definitions + } + ) + if unused_masters: + raise TemplateStructureError( + "spec_lock.md pptx_masters contains Master key(s) without a " + "Layout definition: " + ", ".join(unused_masters) + ) + elif mode == "preserve": + if page_layout_section_present: + raise TemplateStructureError( + "spec_lock.md page_pptx_layouts is reserved for structured mode; " + "preserve mode maps source Layouts directly in pptx_layouts" + ) + seen_slides: set[int] = set() + for page_key, raw_value in layout_rows: + page_match = _LOCK_PAGE_RE.fullmatch(page_key) + if not page_match or int(page_match.group(1)) <= 0: + raise TemplateStructureError( + f"spec_lock.md pptx_layouts key {page_key!r} must be P" + ) + slide_num = int(page_match.group(1)) + if slide_num in seen_slides: + raise TemplateStructureError( + f"spec_lock.md pptx_layouts repeats page P{slide_num:02d}" + ) + seen_slides.add(slide_num) + parts = [part.strip() for part in raw_value.split("|")] if len(parts) not in {1, 2} or not parts[0]: raise TemplateStructureError( f"spec_lock.md P{slide_num:02d} preserve mapping must be " "'' or ' | '" ) layout_key = parts[0] - layout_name = parts[1] if len(parts) == 2 else None - if not _LAYOUT_KEY_RE.fullmatch(layout_key): + if not _LAYOUT_KEY_RE.fullmatch(layout_key): + raise TemplateStructureError( + f"spec_lock.md P{slide_num:02d} has invalid Layout key " + f"{layout_key!r}" + ) + references.append(PptxLayoutReference( + slide_num=slide_num, + layout_key=layout_key, + layout_name=parts[1] if len(parts) == 2 else None, + )) + if not references: raise TemplateStructureError( - f"spec_lock.md P{slide_num:02d} has invalid layout key " - f"{layout_key!r}" + "spec_lock.md preserve mode requires one pptx_layouts row per page" ) - references.append(PptxLayoutReference( - slide_num=slide_num, - layout_key=layout_key, - layout_name=layout_name, - master_key=master_key, - )) - - if mode in {"structured", "preserve"} and not references: - raise TemplateStructureError( - f"spec_lock.md {mode} mode requires one pptx_layouts row per page" - ) - if mode == "structured" and layout_section_present and not layout_rows: - raise TemplateStructureError( - "spec_lock.md structured pptx_layouts section cannot be empty" - ) - layout_contracts: dict[str, tuple[str | None, str | None]] = {} - for reference in references: - contract = (reference.master_key, reference.layout_name) - previous = layout_contracts.setdefault(reference.layout_key, contract) - if previous != contract: + else: + if layout_section_present or page_layout_section_present: raise TemplateStructureError( - f"spec_lock.md layout key {reference.layout_key!r} must be globally " - "unique to one Master and one Layout name" + "spec_lock.md pptx_layouts/page_pptx_layouts sections are not " + "allowed when pptx_structure.mode is flat" ) - if mode == "structured": - unused_masters = sorted( - seen_master_keys - { - reference.master_key - for reference in references - if reference.master_key is not None - } - ) - if unused_masters: - raise TemplateStructureError( - "spec_lock.md pptx_masters contains unreferenced Master key(s): " - + ", ".join(unused_masters) - ) - if mode == "flat" and layout_section_present: - raise TemplateStructureError( - "spec_lock.md pptx_layouts section is not allowed when " - "pptx_structure.mode is flat" - ) return PptxStructureLock( mode=mode, template_adherence=template_adherence, masters=tuple(masters), + layout_definitions=tuple(layout_definitions), layouts=tuple(sorted(references, key=lambda item: item.slide_num)), prototypes=tuple(sorted(prototypes, key=lambda item: item.slide_num)), source_template=source_template, @@ -1446,17 +1546,10 @@ def parse_template_slide( return spec -def parse_template_slides(svg_files: list[Path]) -> list[TemplateSlideSpec]: - """Parse a deck and enforce cross-slide master/layout contracts.""" - specs = [ - parse_template_slide(svg_path, slide_num) - for slide_num, svg_path in enumerate(svg_files, start=1) - ] - if not specs: - raise TemplateStructureError( - "Explicit Layout export requires at least one SVG slide" - ) - +def _validate_template_slide_contracts( + specs: list[TemplateSlideSpec], +) -> None: + """Enforce cross-prototype Master and Layout structure identity.""" by_master: dict[str, list[TemplateSlideSpec]] = {} for spec in specs: by_master.setdefault(spec.master_key, []).append(spec) @@ -1505,6 +1598,19 @@ def parse_template_slides(svg_files: list[Path]) -> list[TemplateSlideSpec]: f"from prototype {prototype.svg_path.name}; repeat the same layout " "layers and placeholder ids/types in the same order" ) + + +def parse_template_slides(svg_files: list[Path]) -> list[TemplateSlideSpec]: + """Parse a deck and enforce cross-slide master/layout contracts.""" + specs = [ + parse_template_slide(svg_path, slide_num) + for slide_num, svg_path in enumerate(svg_files, start=1) + ] + if not specs: + raise TemplateStructureError( + "Explicit Layout export requires at least one SVG slide" + ) + _validate_template_slide_contracts(specs) return specs @@ -1579,6 +1685,33 @@ def parse_optional_layout_slides( return parse_template_slides(svg_files) +def flat_structure_metadata_errors(svg_files: list[Path]) -> list[str]: + """Return every Master/Layout marker forbidden by flat export.""" + errors: list[str] = [] + for svg_path in svg_files: + try: + root = ET.parse(svg_path).getroot() + except (OSError, ET.ParseError) as exc: + errors.append( + f"{svg_path.name}: unable to inspect flat-mode metadata: {exc}" + ) + continue + for elem in root.iter(): + attrs = sorted( + attr + for attr in _FLAT_FORBIDDEN_STRUCTURE_ATTRS + if elem.get(attr) is not None + ) + if not attrs: + continue + element_id = (elem.get("id") or _local_tag(elem)).strip() + errors.append( + f"{svg_path.name}: flat mode forbids Master/Layout structure " + f"metadata on {element_id!r}: " + ", ".join(attrs) + ) + return errors + + def parse_preserve_slides(svg_files: list[Path]) -> list[TemplateSlideSpec]: """Parse preserve-mode slides before source master grouping is known.""" specs = [ @@ -1590,6 +1723,74 @@ def parse_preserve_slides(svg_files: list[Path]) -> list[TemplateSlideSpec]: return specs +def structured_layout_definition_files( + specs: list[TemplateSlideSpec], + structure_lock: PptxStructureLock, +) -> list[Path]: + """Validate the unique Layout roster and return unused prototype SVGs. + + A generated page can be the carrier for a used Layout definition. A Layout + with no generated page must point at one installed template SVG; the builder + converts that SVG on an internal trailing slide and removes the carrier slide + after registering the reusable Layout. + """ + if structure_lock.mode != "structured": + return [] + definitions = { + definition.layout_key: definition + for definition in structure_lock.layout_definitions + } + specs_by_slide = {spec.slide_num: spec for spec in specs} + used_layout_keys = {spec.layout_key for spec in specs} + master_names = { + master.master_key: master.master_name + for master in structure_lock.masters + } + combined_specs = list(specs) + definition_files: list[Path] = [] + next_slide_num = max(specs_by_slide, default=0) + 1 + for definition in structure_lock.layout_definitions: + if definition.prototype_slide_num is not None: + prototype = specs_by_slide.get(definition.prototype_slide_num) + if prototype is None: + raise TemplateStructureError( + f"spec_lock.md Layout {definition.layout_key!r} uses missing " + f"prototype page P{definition.prototype_slide_num:02d}" + ) + elif definition.prototype_svg_path is not None: + prototype = parse_template_slide( + definition.prototype_svg_path, + next_slide_num, + ) + next_slide_num += 1 + combined_specs.append(prototype) + if definition.layout_key not in used_layout_keys: + definition_files.append(definition.prototype_svg_path) + else: + raise TemplateStructureError( + f"spec_lock.md Layout {definition.layout_key!r} has no prototype" + ) + expected_master_name = master_names.get(definition.master_key) + if ( + prototype.layout_key != definition.layout_key + or prototype.layout_name != definition.layout_name + or prototype.master_key != definition.master_key + or prototype.master_name != expected_master_name + ): + raise TemplateStructureError( + f"spec_lock.md Layout {definition.layout_key!r} definition does " + f"not match prototype {prototype.svg_path.name} root identity" + ) + missing_definitions = sorted(used_layout_keys - set(definitions)) + if missing_definitions: + raise TemplateStructureError( + "spec_lock.md pptx_layouts is missing generated Layout key(s): " + + ", ".join(missing_definitions) + ) + _validate_template_slide_contracts(combined_specs) + return definition_files + + def template_lock_errors( specs: list[TemplateSlideSpec], structure_lock: PptxStructureLock, @@ -1606,15 +1807,22 @@ def template_lock_errors( expected_slides = set(references) missing = sorted(actual_slides - expected_slides) extra = sorted(expected_slides - actual_slides) + assignment_section = ( + "page_pptx_layouts" + if structure_lock.mode == "structured" + else "pptx_layouts" + ) if missing: pages = ", ".join(f"P{slide_num:02d}" for slide_num in missing) errors.append( - f"spec_lock.md pptx_layouts is missing generated page(s): {pages}" + f"spec_lock.md {assignment_section} is missing generated page(s): " + f"{pages}" ) if extra: pages = ", ".join(f"P{slide_num:02d}" for slide_num in extra) errors.append( - f"spec_lock.md pptx_layouts references absent page(s): {pages}" + f"spec_lock.md {assignment_section} references absent page(s): " + f"{pages}" ) for spec in specs: reference = references.get(spec.slide_num) @@ -1623,26 +1831,40 @@ def template_lock_errors( if spec.layout_key != reference.layout_key: errors.append( f"{spec.svg_path.name}: data-pptx-layout={spec.layout_key!r} " - f"does not match spec_lock P{spec.slide_num:02d} layout key " + f"does not match spec_lock P{spec.slide_num:02d} Layout key " f"{reference.layout_key!r}" ) - if reference.layout_name and spec.layout_name != reference.layout_name: - errors.append( - f"{spec.svg_path.name}: data-pptx-layout-name={spec.layout_name!r} " - f"does not match spec_lock P{spec.slide_num:02d} layout name " - f"{reference.layout_name!r}" - ) - if reference.master_key and spec.master_key != reference.master_key: - errors.append( - f"{spec.svg_path.name}: data-pptx-master={spec.master_key!r} " - f"does not match spec_lock P{spec.slide_num:02d} Master key " - f"{reference.master_key!r}" - ) + if structure_lock.mode == "preserve": + if reference.layout_name and spec.layout_name != reference.layout_name: + errors.append( + f"{spec.svg_path.name}: data-pptx-layout-name=" + f"{spec.layout_name!r} does not match spec_lock " + f"P{spec.slide_num:02d} Layout name " + f"{reference.layout_name!r}" + ) if structure_lock.mode == "structured": + definitions = { + definition.layout_key: definition + for definition in structure_lock.layout_definitions + } master_names = { master.master_key: master.master_name for master in structure_lock.masters } for spec in specs: + definition = definitions.get(spec.layout_key) + if definition is not None: + if spec.layout_name != definition.layout_name: + errors.append( + f"{spec.svg_path.name}: data-pptx-layout-name=" + f"{spec.layout_name!r} does not match Layout " + f"{spec.layout_key!r} name {definition.layout_name!r}" + ) + if spec.master_key != definition.master_key: + errors.append( + f"{spec.svg_path.name}: data-pptx-master=" + f"{spec.master_key!r} does not match Layout " + f"{spec.layout_key!r} Master {definition.master_key!r}" + ) expected_name = master_names.get(spec.master_key) if expected_name is not None and spec.master_name != expected_name: errors.append( @@ -1650,6 +1872,10 @@ def template_lock_errors( f"{spec.master_name!r} does not match spec_lock Master " f"{spec.master_key!r} name {expected_name!r}" ) + try: + structured_layout_definition_files(specs, structure_lock) + except TemplateStructureError as exc: + errors.append(str(exc)) return errors diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/pptx_package/template_validation.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/pptx_package/template_validation.py index f7499ac3..82fd22fd 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/pptx_package/template_validation.py +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/pptx_package/template_validation.py @@ -49,6 +49,7 @@ from .template_structure import ( PML_NS = "http://schemas.openxmlformats.org/presentationml/2006/main" DML_NS = "http://schemas.openxmlformats.org/drawingml/2006/main" REL_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships" +P14_NS = "http://schemas.microsoft.com/office/powerpoint/2010/main" SLIDE_LAYOUT_REL_TYPE = ( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" ) @@ -58,6 +59,9 @@ SLIDE_REL_TYPE = ( SLIDE_MASTER_REL_TYPE = ( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" ) +THEME_REL_TYPE = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" +) SLIDE_LAYOUT_CONTENT_TYPE = ( "application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml" ) @@ -156,6 +160,51 @@ class _PackageReader: return result +def _validate_unique_creation_ids( + reader: _PackageReader, + parts: set[str], +) -> None: + """Reject cloned PowerPoint parts that retain the same p14:creationId.""" + owners: dict[int, str] = {} + for part in sorted(parts): + root = reader.xml(part) + if root is None: + continue + c_sld = root.find(f"{{{PML_NS}}}cSld") + if c_sld is None: + continue + seen_in_part: set[int] = set() + for creation_id in c_sld.findall( + f"{{{PML_NS}}}extLst/{{{PML_NS}}}ext/" + f"{{{P14_NS}}}creationId" + ): + raw_value = creation_id.get("val") + try: + value = int(raw_value or "") + except ValueError: + reader.errors.append( + f"{part} has invalid p14:creationId value {raw_value!r}" + ) + continue + if value < 0 or value > OOXML_UINT32_MAX: + reader.errors.append( + f"{part} p14:creationId {value} is outside OOXML UInt32" + ) + continue + if value in seen_in_part: + reader.errors.append( + f"{part} repeats p14:creationId {value}" + ) + continue + seen_in_part.add(value) + previous_owner = owners.setdefault(value, part) + if previous_owner != part: + reader.errors.append( + f"p14:creationId {value} is shared by " + f"{previous_owner} and {part}" + ) + + def _top_level_shape_names( root: ET.Element, context: str, @@ -759,6 +808,39 @@ def _validate_presentation_master_registration( ) +def _validate_master_theme_ownership( + reader: _PackageReader, + master_parts: set[str], +) -> None: + """Require a separate Theme part for every structured Slide Master.""" + owners: dict[str, str] = {} + for master_part in sorted(master_parts): + resolved = _single_relationship_target( + reader, + master_part, + THEME_REL_TYPE, + f"Master {master_part}", + ) + if resolved is None: + continue + _relationship, theme_part = resolved + if not ( + theme_part.startswith("ppt/theme/") + and theme_part.endswith(".xml") + ): + reader.errors.append( + f"Master {master_part} targets non-Theme part {theme_part}" + ) + continue + reader.xml(theme_part) + previous_owner = owners.setdefault(theme_part, master_part) + if previous_owner != master_part: + reader.errors.append( + f"Theme {theme_part} is shared by structured Masters " + f"{previous_owner} and {master_part}" + ) + + def _validate_presentation_slide_registration( reader: _PackageReader, slide_parts: set[str], @@ -785,23 +867,32 @@ def validate_pptx_template_package( pptx_path: str | Path, specs: list[TemplateSlideSpec], *, + layout_specs: list[TemplateSlideSpec] | None = None, + expected_layout_parts: dict[str, str] | None = None, + expected_master_parts: dict[str, str] | None = None, expected_backgrounds: dict[str, str | None] | None = None, expected_shape_rosters: dict[str, tuple[str, ...]] | None = None, ) -> None: """Validate a finished structured PPTX against its explicit SVG contract. - Export supplies pre-packaging background and shape expectations for exact - serialization read-back. Callers that only have the finished package still - receive the portable structure, ownership, and relationship checks. + ``specs`` describes published slides. ``layout_specs`` may additionally + include internal prototypes for unused Layouts. Export supplies exact part, + background, and shape expectations for deterministic serialization + read-back. Callers with only published-slide specs retain the original + portable relationship checks. """ if not specs: raise ValueError("structured package validation requires at least one slide spec") + structure_specs = layout_specs or specs specs_by_layout: dict[str, list[TemplateSlideSpec]] = {} + public_specs_by_layout: dict[str, list[TemplateSlideSpec]] = {} bindings_by_layout: dict[str, tuple[TemplatePlaceholderBinding, ...]] = {} try: - for spec in specs: + for spec in structure_specs: specs_by_layout.setdefault(spec.layout_key, []).append(spec) + for spec in specs: + public_specs_by_layout.setdefault(spec.layout_key, []).append(spec) for layout_key, layout_specs in specs_by_layout.items(): bindings_by_layout[layout_key] = template_placeholder_bindings( layout_specs[0] @@ -849,8 +940,22 @@ def validate_pptx_template_package( exact=True, ordered=True, ) - layout_parts_by_key: dict[str, str] = {} - keys_by_layout_part: dict[str, str] = {} + layout_parts_by_key = dict(expected_layout_parts or {}) + keys_by_layout_part = { + part: key for key, part in layout_parts_by_key.items() + } + if len(keys_by_layout_part) != len(layout_parts_by_key): + errors.append( + "expected Layout part mapping assigns one part to multiple keys" + ) + if expected_layout_parts is not None and ( + set(expected_layout_parts) != set(specs_by_layout) + ): + errors.append( + "expected Layout key roster differs from the SVG contract; " + f"missing={sorted(set(specs_by_layout) - set(expected_layout_parts))}, " + f"extra={sorted(set(expected_layout_parts) - set(specs_by_layout))}" + ) slide_roots: dict[int, ET.Element] = {} for spec in specs: @@ -876,10 +981,7 @@ def validate_pptx_template_package( ) continue reader.xml(layout_part) - previous_part = layout_parts_by_key.setdefault( - spec.layout_key, - layout_part, - ) + previous_part = layout_parts_by_key.setdefault(spec.layout_key, layout_part) if previous_part != layout_part: errors.append( f"layout key {spec.layout_key!r} targets both {previous_part} " @@ -898,8 +1000,25 @@ def validate_pptx_template_package( used_master_parts: set[str] = set() layout_parts_by_master: dict[str, set[str]] = {} master_specs_by_part: dict[str, TemplateSlideSpec] = {} - master_parts_by_key: dict[str, str] = {} - keys_by_master_part: dict[str, str] = {} + master_parts_by_key = dict(expected_master_parts or {}) + keys_by_master_part = { + part: key for key, part in master_parts_by_key.items() + } + expected_master_keys = { + spec.master_key for spec in structure_specs + } + if len(keys_by_master_part) != len(master_parts_by_key): + errors.append( + "expected Master part mapping assigns one part to multiple keys" + ) + if expected_master_parts is not None and ( + set(expected_master_parts) != expected_master_keys + ): + errors.append( + "expected Master key roster differs from the SVG contract; " + f"missing={sorted(expected_master_keys - set(expected_master_parts))}, " + f"extra={sorted(set(expected_master_parts) - expected_master_keys)}" + ) for layout_key, layout_specs in specs_by_layout.items(): prototype = layout_specs[0] layout_part = layout_parts_by_key.get(layout_key) @@ -988,7 +1107,7 @@ def validate_pptx_template_package( "for exact read-back" ) slide_placeholders: dict[int, dict[int, _Placeholder]] = {} - for spec in layout_specs: + for spec in public_specs_by_layout.get(layout_key, []): slide_root = slide_roots.get(spec.slide_num) if slide_root is None: continue @@ -1373,8 +1492,13 @@ def validate_pptx_template_package( errors, "Master", ) + _validate_unique_creation_ids( + reader, + expected_slide_parts | expected_layout_parts | used_master_parts, + ) _validate_presentation_slide_registration(reader, expected_slide_parts) _validate_presentation_master_registration(reader, used_master_parts) + _validate_master_theme_ownership(reader, used_master_parts) except (OSError, zipfile.BadZipFile) as exc: raise ValueError(f"cannot read template PPTX package {path}: {exc}") from exc diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/template_preview_pptx.py b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/template_preview_pptx.py index 0c984de0..58ca103e 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/template_preview_pptx.py +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/template_preview_pptx.py @@ -46,6 +46,10 @@ _FRONTMATTER_ID_RE = re.compile( r"^(?:template_id|deck_id|layout_id)\s*:\s*(.+?)\s*$", re.MULTILINE, ) +_REPLICATION_MODE_RE = re.compile( + r"^replication_mode\s*:\s*(standard|fidelity|mirror)\s*$", + re.MULTILINE, +) _FONT_SIZE_RE = re.compile(r"^([0-9]+(?:\.[0-9]+)?)(?:px)?$") _FILENAME_UNSAFE_RE = re.compile(r"[\\/:*?\"<>|\x00-\x1f]+") _TITLE_PLACEHOLDERS = frozenset({"title", "subtitle"}) @@ -87,6 +91,13 @@ def _template_id(spec_path: Path, workspace: Path) -> str: return safe or "template" +def _replication_mode(spec_path: Path) -> str: + """Read the template replication mode, defaulting legacy packages to standard.""" + text = spec_path.read_text(encoding="utf-8") + match = _REPLICATION_MODE_RE.search(text) + return match.group(1) if match else "standard" + + def _style_property(style: str, name: str) -> str | None: """Return one inline CSS declaration value.""" for declaration in style.split(";"): @@ -146,12 +157,62 @@ def _master_text_style(svg_files: list[Path]) -> tuple[MasterTextStyleSpec, floa ) -def _verify_output(output_path: Path) -> tuple[int, int, int]: - """Reopen the review deck and return slide/master/layout counts.""" +def _verify_output( + output_path: Path, + *, + require_full_placeholder_frames: bool, +) -> tuple[int, int, int, int]: + """Reopen the review deck and verify counts plus authored placeholder frames.""" presentation = Presentation(str(output_path)) master_count = len(presentation.slide_masters) layout_count = sum(len(master.slide_layouts) for master in presentation.slide_masters) - return len(presentation.slides), master_count, layout_count + placeholder_count = 0 + if require_full_placeholder_frames: + for slide_number, slide in enumerate(presentation.slides, 1): + layout_placeholders = { + shape.placeholder_format.idx: shape + for shape in slide.slide_layout.placeholders + } + slide_placeholders = { + shape.placeholder_format.idx: shape + for shape in slide.placeholders + } + if set(slide_placeholders) != set(layout_placeholders): + raise ValueError( + f"review slide {slide_number} placeholder indexes do not match " + f"its Layout: {sorted(slide_placeholders)} != " + f"{sorted(layout_placeholders)}" + ) + for placeholder_idx, slide_shape in slide_placeholders.items(): + layout_shape = layout_placeholders[placeholder_idx] + if ( + slide_shape.placeholder_format.type + != layout_shape.placeholder_format.type + ): + raise ValueError( + f"review slide {slide_number} placeholder {placeholder_idx} " + "type does not match its Layout" + ) + slide_frame = ( + slide_shape.left, + slide_shape.top, + slide_shape.width, + slide_shape.height, + ) + layout_frame = ( + layout_shape.left, + layout_shape.top, + layout_shape.width, + layout_shape.height, + ) + if slide_frame != layout_frame: + raise ValueError( + f"review slide {slide_number} placeholder {placeholder_idx} " + f"uses a tight/local frame {slide_frame}; expected full " + f"Layout frame {layout_frame}" + ) + placeholder_count += 1 + return len(presentation.slides), master_count, layout_count, placeholder_count def build_parser() -> argparse.ArgumentParser: @@ -202,7 +263,12 @@ def main(argv: list[str] | None = None) -> int: if not svg_files: raise ValueError(f"template directory has no SVG prototypes: {template_dir}") - template_id = _template_id(template_dir / "design_spec.md", workspace) + spec_path = template_dir / "design_spec.md" + template_id = _template_id(spec_path, workspace) + replication_mode = _replication_mode(spec_path) + use_full_placeholder_frames = ( + not args.visual_only and replication_mode != "mirror" + ) output_path = ( Path(args.output).expanduser().resolve() if args.output @@ -225,8 +291,11 @@ def main(argv: list[str] | None = None) -> int: print(f" SVG prototypes: {len(svg_files)}") if args.visual_only: print(" Review mode: visual-only legacy compatibility") + elif replication_mode == "mirror": + print(" Review placeholder frames: preserved source Slide geometry") else: print(f" Review Master defaults: title {title_px:g}px, body {body_px:g}px") + print(" Review placeholder frames: full Layout bounds") print(f" Output: {output_path}") success = create_pptx_with_native_svg( @@ -240,13 +309,18 @@ def main(argv: list[str] | None = None) -> int: image_optimize=False, native_objects=True, pptx_structure="flat" if args.visual_only else "structured", + use_layout_placeholder_frames=use_full_placeholder_frames, master_text_style_spec=text_style, + structure_name=template_id, ) if not success or not output_path.is_file(): print("Error: template preview export did not produce a PPTX", file=sys.stderr) return 1 - slide_count, master_count, layout_count = _verify_output(output_path) + slide_count, master_count, layout_count, placeholder_count = _verify_output( + output_path, + require_full_placeholder_frames=use_full_placeholder_frames, + ) if slide_count != len(svg_files): print( "Error: review PPTX slide count does not match the template SVG roster " @@ -256,9 +330,15 @@ def main(argv: list[str] | None = None) -> int: return 1 label = "Visual-only template preview" if args.visual_only else "Template preview" + placeholder_status = ( + f", {placeholder_count} full-frame placeholder(s)" + if use_full_placeholder_frames + else "" + ) print( f"[OK] {label} verified: " - f"{slide_count} slides, {master_count} master(s), {layout_count} layout(s)" + f"{slide_count} slides, {master_count} master(s), " + f"{layout_count} layout(s){placeholder_status}" ) print(output_path) return 0 diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/README.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/README.md index ec696647..e79f6aee 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/README.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/README.md @@ -50,6 +50,6 @@ Logo filenames are descriptive, not contractual — `templates/design_spec.md` ## Discovery index -[brands_index.json](./brands_index.json) is a slim machine-readable map (`brand_id → { summary, primary_color }`). It is refreshed by `register_template.py --kind brand ` after a brand is created or edited. +[brands_index.json](./brands_index.json) is a slim machine-readable map (`brand_id → { summary, primary_color }`). Refresh it with `register_template.py --kind brand ` after a brand is created or edited. Registration rejects incomplete frontmatter, mismatched IDs, page SVGs, missing required identity sections, invalid or inconsistent colors/provenance, and broken workspace-local asset references. Listing the index does not trigger any pipeline action — Step 3 triggers only on an explicit directory path supplied by the user, regardless of whether the brand appears in the index. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/anthropic/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/anthropic/templates/design_spec.md index 46378345..062f1bae 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/anthropic/templates/design_spec.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/anthropic/templates/design_spec.md @@ -1,11 +1,11 @@ --- brand_id: anthropic kind: brand -summary: Anthropic brand identity — AI/LLM tech talks, developer conferences, technical training, product launches +summary: Anthropic / Claude brand family — AI research, product talks, developer conferences, technical training, and launches primary_color: "#D97757" --- -# Anthropic Brand Specification +# Anthropic / Claude Brand Family Specification > Identity-only preset. No SVG page roster — pages are composed freely under these constraints. @@ -13,25 +13,23 @@ primary_color: "#D97757" | Property | Value | |---|---| -| Brand Name | Anthropic | -| Use Cases | AI / LLM tech talks, developer conferences, technical training, product launches, research updates | +| Brand Name | Anthropic / Claude | +| Use Cases | AI / LLM research updates, Claude product talks, developer conferences, technical training, product launches | | Tone | Tech-forward, professional, modern, conclusion-first, restrained | +| Sources | Bundled Claude SVG assets for literal logo colors; Anthropic public materials reviewed 2026-07-13 | ## II. Color Scheme | Role | HEX | Provenance | Notes | |---|---|---|---| -| primary | `#D97757` | fact | Anthropic Orange — extracted from `anthropic_mark.svg` (matches the mark fill on claude.com header) | -| neutral-dark | `#191919` | fact | Anthropic near-black — body text, dark surfaces, chart base | -| bg | `#FFFFFF` | fact | Pure white page background | -| accent (info) | `#4A90D9` | approx | Tech blue — flow / process, links, interactive elements | -| accent (positive) | `#10B981` | approx | Mint green — recommended options, success states | -| accent (alert) | `#EF4444` | approx | Coral red — risks, cautions, warnings | +| primary | `#D97757` | fact | Claude coral — literal fill in the bundled Claude star mark | +| neutral-dark | `#191919` | fact | Literal fill in the bundled Claude wordmark | +| bg | `#FFFFFF` | approx | Default light presentation background | | surface | `#F8FAFC` | approx | Off-white — card background | | border | `#E2E8F0` | approx | Light gray — card borders, dividers | | muted-text | `#64748B` | approx | Slate gray — secondary text, chart labels | -The first three rows are the official triad; the accent / surface / border / muted rows are presentation conventions on top of the official identity, derived to match Anthropic's restrained product UI tone. The accent triple (info / positive / alert) differentiates content types (blue = process, green = recommended, red = risk). Strategist may rotate dominance per page. +The first two rows are literal Claude asset facts. Background and neutral rows are presentation conventions, not official company tokens. Choose semantic chart/status colors per deck; do not lock an invented info/success/alert trio as Anthropic identity. ## III. Typography @@ -40,19 +38,20 @@ The first three rows are the official triad; the accent / surface / border / mut | title | `"Styrene A", "Helvetica Neue", Arial, "Microsoft YaHei", sans-serif` | 600–700 | | body | `"Anthropic Sans", "Helvetica Neue", Arial, "Microsoft YaHei", sans-serif` | 400 | -> Anthropic's official typefaces are `Styrene A` (titles) and `Anthropic Sans` (body) — both proprietary and unlikely to be installed on viewer machines. Decks should either embed the fonts into the PPTX or accept the `Helvetica Neue` → `Arial` / `Microsoft YaHei` fallback chain. When locking, Strategist notes "official Anthropic typefaces require install or PPTX embed". +> `Styrene A` and `Anthropic Sans` are proprietary and unlikely to be installed on viewer machines. PPT Master does not bundle or automatically embed them; use the declared fallback chain unless the user supplies an installed/approved font workflow. ## IV. Logo -Anthropic uses a six-petal star **mark** that is most commonly seen locked up with a product wordmark. The bundled lockup pairs the mark with the **Claude** wordmark, since that is the live lockup on claude.com. Pick by context, never combine on the same page. +This preset intentionally combines Anthropic company voice with Claude product visuals. The bundled star and wordmark belong to Claude; they are not relabeled as an Anthropic corporate mark. Pick one Claude asset by context and never combine several lockups on the same page. | File | Form | Usage | |---|---|---| -| `../images/anthropic_claude_lockup.svg` | Mark + "Claude" wordmark (112×24) | Cover hero, ending sign-off, any moment when the brand needs to read as Claude-the-product at a glance | -| `../images/anthropic_mark.svg` | Square orange six-petal mark (24×24) | Header / footer corners, page-number neighbors, tight badges, any small-size moment where the lockup would become illegible — also the recommended choice when the deck is about Anthropic the company rather than Claude the product | +| `../images/anthropic_claude_lockup.svg` | Claude star + "Claude" wordmark (112×24) | Cover hero, ending sign-off, and Claude product moments | +| `../images/anthropic_mark.svg` | Claude square star mark (24×24; historical filename retained) | Header/footer corners, page-number neighbors, and compact Claude product badges | | `../images/claude_wordmark.svg` | "Claude" wordmark alone (82×24) | When the visual context already establishes the brand and only the product name needs to be reinforced | -- Cover: prefer the lockup when the deck is Claude-facing; prefer the mark alone when the deck is Anthropic-company-facing +- Claude-facing cover: prefer the complete Claude lockup +- Anthropic-company-facing cover: use editable `Anthropic` text unless an approved corporate lockup is supplied; do not substitute the Claude wordmark - Per-page: optional — only when one of these genuinely fits the layout; do not stamp every page - Clearspace: leave at least 0.5× mark height of empty space on all sides; never overlap text or photographic backgrounds - Mark color is fixed at `#D97757`; wordmark inherits the page text color (default `#191919` on light bg, `#FFFFFF` on dark) @@ -68,4 +67,4 @@ Anthropic uses a six-petal star **mark** that is most commonly seen locked up wi - Preference: stroke -> Outline / stroke icons read as "research / engineering" and align with Anthropic's restrained product UI aesthetic. When the deck uses `templates/icons/`, prefer `tabler` or `lucide` stroke families over filled libraries. +> This is a presentation convention, not an official brand token. Prefer `tabler` or `lucide` stroke families when they fit the deck; keep one icon family consistent. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/brands_index.json b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/brands_index.json index 39955707..25def00c 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/brands_index.json +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/brands_index.json @@ -1,15 +1,19 @@ { "anthropic": { - "summary": "Anthropic brand identity — AI/LLM tech talks, developer conferences, technical training, product launches", + "summary": "Anthropic / Claude brand family — AI research, product talks, developer conferences, technical training, and launches", "primary_color": "#D97757" }, "google": { "summary": "Google brand identity — multi-product corporate decks, developer events (Google I/O style), education and training in the Google ecosystem", "primary_color": "#4285F4" }, + "中国电信": { + "summary": "China Telecom brand identity for digital infrastructure, government-enterprise solutions, transformation planning, and corporate reporting", + "primary_color": "#004EA2" + }, "中国电建": { "summary": "POWERCHINA brand identity for engineering project reports, technical proposals, business negotiations, and corporate promotion", - "primary_color": "#00418D" + "primary_color": "#004EA1" }, "中汽研": { "summary": "CATARC brand identity for product certification, evaluation reports, automotive technology promotion, and business visits", diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/google/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/google/templates/design_spec.md index bc6a36bb..450f1bcd 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/google/templates/design_spec.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/google/templates/design_spec.md @@ -16,6 +16,7 @@ primary_color: "#4285F4" | Brand Name | Google | | Use Cases | Product launches, developer events (Google I/O style), corporate updates, multi-product decks, ecosystem education / training | | Tone | Modern, friendly, optimistic, clear, multi-color expressive | +| Sources | Bundled Google SVG assets; [Google Brand Resource Center](https://about.google/brand-resource-center/guidance/), reviewed 2026-07-13 | ## II. Color Scheme @@ -26,7 +27,7 @@ primary_color: "#4285F4" | accent (warm) | `#FBBC05` | fact | Google Yellow | | accent (alert) | `#EA4335` | fact | Google Red | | text | `#202124` | approx | Standard Material / Google product UI text | -| bg | `#FFFFFF` | fact | | +| bg | `#FFFFFF` | approx | Default light presentation background | The four primary brand colors (Blue / Green / Yellow / Red) carry equal weight in Google brand usage; the `primary` / `secondary` / `accent` role split above is a slide-layout presentation hierarchy convention, not a brand prominence statement. Strategist may rotate any of the four into the dominant role per page rhythm. @@ -37,7 +38,7 @@ The four primary brand colors (Blue / Green / Yellow / Red) carry equal weight i | title | `Google Sans, Roboto, "Microsoft YaHei", sans-serif` | 500–700 | | body | `Roboto, "Microsoft YaHei", sans-serif` | 400 | -> `Google Sans` is a proprietary brand font; decks rendering on machines without it installed should either embed it into the PPTX or accept the `Roboto` / `Microsoft YaHei` fallback. When locking, Strategist notes "requires install or PPTX embed". +> `Google Sans` is proprietary. PPT Master does not bundle or automatically embed it; use the `Roboto` / `Microsoft YaHei` fallback unless the user supplies an installed/approved font workflow. ## IV. Logo @@ -50,7 +51,8 @@ Google uses a dual-lockup brand system — pick by context, never combine on the - Cover: prefer wordmark - Per-page: optional — only when wordmark or G mark genuinely fits the layout; do not stamp every page -- Clearspace: leave at least 0.5× logo height of empty space on all sides; never overlap text or photographic backgrounds +- Use only unmodified approved artwork and follow the official guidance for the actual context; never imply affiliation, sponsorship, or endorsement +- Clearspace: follow the applicable official asset guidance; never crowd the logo or place it on a busy background ## V. Voice & Tone @@ -61,6 +63,6 @@ Google uses a dual-lockup brand system — pick by context, never combine on the ## VI. Icon Style -- Preference: filled +- Preference: one consistent Material-aligned family; filled or stroke according to the deck context -> Aligns with Material Icons' default filled style. When the deck uses `templates/icons/`, prefer `tabler-filled` or `chunk-filled`; avoid stroke-only libraries to stay consistent with Google's product UI aesthetic. +> This is a presentation convention, not permission to imitate Google's visual identity. When the deck uses `templates/icons/`, choose one compatible family and keep weight/fill treatment consistent. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/中国电信/images/logo.png b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/中国电信/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..2cf3f7e180d2cb2aad516cd694533ec2cb037c4d GIT binary patch literal 8325 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 Identity-only preset. No SVG page roster; pages are composed freely under these brand constraints. + +## I. Brand Overview + +| Property | Value | +|---|---| +| Brand Name | China Telecom / 中国电信 | +| Use Cases | Digital infrastructure reports, government-enterprise solutions, transformation planning, corporate reporting, and service presentations | +| Tone | Formal, trusted, service-oriented, technically credible | +| Sources | Bundled China Telecom logo for literal color evidence; [China Telecom official website](https://www.chinatelecom.com.cn/), reviewed 2026-07-13 | + +## II. Color Scheme + +| Role | HEX | Provenance | Notes | +|---|---|---|---| +| primary | `#004EA2` | approx | Dominant blue sampled from the bundled raster China Telecom logo | +| text | `#1F2937` | approx | Primary body text on light backgrounds | +| muted-text | `#6B7280` | approx | Secondary descriptions and annotations | +| bg | `#FFFFFF` | approx | Standard light presentation background | +| surface | `#F8FAFC` | approx | Light card and module surfaces | +| border | `#E5E7EB` | approx | Dividers, table borders, and restrained technical grids | + +The primary blue is an exact pixel sample from the bundled raster logo, but remains `approx` because no authoritative token value is bundled. The neutrals are presentation conventions. Red accents found in individual retained decks are deck-specific and must not be promoted to a default China Telecom brand color without stronger evidence. + +## III. Typography + +| Role | Family | Weight | +|---|---|---| +| title | `"Microsoft YaHei", "微软雅黑", "SimHei", Arial, sans-serif` | 700 | +| body | `"Microsoft YaHei", "微软雅黑", Arial, sans-serif` | 400 | +| data | `Arial, "Microsoft YaHei", sans-serif` | 600-700 | + +Use PowerPoint-safe CJK fonts by default. Keep English technical labels, network standards, and data labels in Arial where that improves scanning. This preset does not bundle or automatically embed proprietary fonts. + +## IV. Logo + +The bundled asset is the default China Telecom corporate lockup. Use it unmodified and keep product, campaign, and event identities out of the base brand preset. + +| File | Form | Usage | +|---|---|---| +| `../images/logo.png` | China Telecom corporate lockup (252x69) | Cover, ending, and restrained page-header branding | + +- Cover / ending: use the full lockup at a readable size. +- Content pages: use the lockup only when the title area has sufficient space; avoid repeating it as oversized decoration. +- Keep clearspace around the lockup and avoid busy image backgrounds. +- On dark backgrounds, use an owner-approved reverse asset when supplied; otherwise place this logo on a clean white backing plate. +- Do not substitute 5G, campaign, slogan, or event assets for the corporate lockup unless the presentation scope explicitly calls for that identity. +- External publication must follow the owner's trademark and asset permissions; packaging the logo does not grant usage rights. + +## V. Voice & Tone + +- Formality: formal-neutral +- Person: organization-first, "we / 我们" only when speaking as China Telecom +- Emoji: avoid +- Abbreviations: spell out organization and service names on first use; retain standard network terms such as 5G when context is clear +- Style: emphasize service reliability, secure infrastructure, customer value, public responsibility, and measurable digital outcomes + +## VI. Icon Style + +- Preference: clean stroke or solid geometric icons +- Recommended libraries: `tabler-outline`, `lucide`, or one consistent filled family when higher visual weight is needed +- Prefer network, cloud, security, service, data, infrastructure, and industry-solution metaphors. Avoid decorative telecom waves that could be mistaken for an official mark. +- This icon guidance is a presentation convention, not an official China Telecom icon token set. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/中国电建/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/中国电建/templates/design_spec.md index 0e21fd32..19c80cc3 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/中国电建/templates/design_spec.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/中国电建/templates/design_spec.md @@ -2,7 +2,7 @@ brand_id: 中国电建 kind: brand summary: POWERCHINA brand identity for engineering project reports, technical proposals, business negotiations, and corporate promotion -primary_color: "#00418D" +primary_color: "#004EA1" --- # POWERCHINA (中国电建) Brand Specification @@ -16,22 +16,21 @@ primary_color: "#00418D" | Brand Name | POWERCHINA / 中国电建 | | Use Cases | Engineering project reports, technical proposal presentations, business negotiations, corporate promotion, annual summaries | | Tone | Professional, composed, international, state-owned enterprise style | +| Sources | Bundled logo assets for literal colors; [POWERCHINA Brand and Visual Identity Manual (2025) release page](https://11j.powerchina.cn/col/col16780/art/2025/art_daed13ac0e294a56a31033ced7689708.html), reviewed 2026-07-13 | ## II. Color Scheme | Role | HEX | Provenance | Notes | |---|---|---|---| -| primary | `#00418D` | approx | POWERCHINA Blue, inherited from the existing POWERCHINA deck templates | -| secondary | `#002B5C` | approx | Deep blue for chapter pages, dark headers, and gradient bases | -| accent (blue) | `#0066CC` | approx | Bright blue for charts, links, and secondary emphasis | -| accent (light) | `#4A90D9` | approx | Sky blue for tertiary highlights and decorative rules | -| accent (red) | `#C41E3A` | approx | China red for milestones, key data, and national-strength emphasis | -| accent (gold) | `#C9A227` | approx | Honors, achievements, and award moments | +| primary | `#004EA1` | approx | Dominant blue sampled from the bundled raster POWERCHINA group symbol | +| secondary | `#C90A4F` | approx | Dominant magenta-red sampled from the bundled raster POWERCHINA group symbol | | text | `#1A1A1A` | approx | Primary body text on light backgrounds | | muted-text | `#4A5568` | approx | Secondary descriptions and annotations | | bg | `#FFFFFF` | approx | Standard light presentation background | | surface | `#F4F6F8` | approx | Light gray card and module surfaces | +The two symbol colors are exact pixel samples from the bundled raster asset, but remain `approx` because no authoritative token values are bundled. The neutral presentation colors are also practical approximations, not claims about official POWERCHINA design tokens. + ## III. Typography | Role | Family | Weight | @@ -44,19 +43,22 @@ Use PowerPoint-safe CJK fonts by default. Keep English technical labels in Arial ## IV. Logo -POWERCHINA templates may use the group brand logo or subsidiary logos depending on the presenting entity. Pick one primary logo per deck and avoid mixing several logos on every page. +This preset defaults to the POWERCHINA group as the presenting entity. Subsidiary marks are explicit alternates only when that subsidiary owns the presentation; pick one presenting entity per deck. | File | Form | Usage | |---|---|---| -| `../images/电建logo.png` | POWERCHINA symbol / primary mark (234x236) | Cover, ending, and compact brand moments where the group identity is required | +| `../images/电建logo.png` | POWERCHINA group symbol / primary mark (234x236) | Cover, ending, and compact brand moments where the group identity is required | | `../images/中国水务logo.png` | China Water logo lockup (1108x190) | Subsidiary-led water-business reports; cover or ending lockup | | `../images/华东院logo.png` | East China Institute logo lockup (1438x300) | Institute-led technical reports and engineering proposals | | `../images/水电三局logo.png` | Sinohydro Bureau 3 logo lockup (629x75) | Bureau-led project reports and construction updates | - Cover / ending: use the selected primary logo at readable size. - Per-page header: optional; use a compact logo only when it does not crowd the title bar. +- Do not mix the group mark and several subsidiary marks as routine page chrome. Use co-branding only when the presentation brief explicitly requires it. +- If a subsidiary needs materially different colors, typography, or recurring identity rules, create a separate brand workspace for that entity. - Dark backgrounds: prefer white/inverted treatment when available; otherwise place the logo on a white backing plate. - Clearspace: leave at least 0.5x logo height around the mark or lockup. +- External publication must follow the owner-provided trademark and visual-identity permissions; packaging these assets does not grant usage rights. ## V. Voice & Tone @@ -71,3 +73,4 @@ POWERCHINA templates may use the group brand logo or subsidiary logos depending - Preference: filled or sturdy stroke icons - Recommended libraries: `tabler-filled`, `chunk-filled`, or `tabler-outline` with heavier stroke - Avoid thin decorative icons for engineering / construction content; prefer solid symbols, process arrows, infrastructure metaphors, and chart-friendly pictograms. +- This icon guidance is a presentation convention, not an official POWERCHINA icon token set. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/中汽研/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/中汽研/templates/design_spec.md index fc051b03..f1c545a7 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/中汽研/templates/design_spec.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/brands/中汽研/templates/design_spec.md @@ -16,23 +16,22 @@ primary_color: "#004098" | Brand Name | CATARC / 中汽研 | | Use Cases | Product certification display, evaluation presentations, automotive technology promotion, business visits, high-end technical reporting | | Tone | Professional, authoritative, trustworthy, technical-consulting style | +| Sources | Bundled CATARC logo assets and the validated CATARC deck identity, reviewed 2026-07-13 | ## II. Color Scheme | Role | HEX | Provenance | Notes | |---|---|---|---| -| primary | `#004098` | approx | CATARC deep blue, inherited from the standard CATARC deck template | -| secondary | `#003366` | approx | Dark business blue for covers, chapter pages, and formal section headers | -| accent (blue) | `#0050B3` | approx | Bright blue for technology emphasis and gradients | -| accent (tech) | `#1890FF` | approx | Modern tech blue for forward-looking automotive topics | -| accent (cyan) | `#00E5FF` | approx | High-energy data / future-tech highlights; use sparingly | -| accent (red) | `#CC0000` | approx | Certification warnings, failed checks, and key risk emphasis | +| primary | `#004098` | approx | Working primary blue aligned with the validated CATARC deck template | +| secondary | `#003B82` | approx | Dark blue for chapter pages, headers, and restrained depth | | text | `#333333` | approx | Primary body text on light backgrounds | | muted-text | `#666666` | approx | Secondary descriptions and notes | | bg | `#FFFFFF` | approx | Standard light presentation background | -| surface | `#F5F5F5` | approx | Secondary content blocks and cards | +| surface | `#F8FAFC` | approx | Secondary content blocks and cards | | border | `#E0E0E0` | approx | Dividers, table borders, and technical grids | +This compact palette intentionally matches the retained CATARC deck identity. It is an internal presentation approximation, not a claim about official CATARC design tokens. Derive success, warning, and error colors from the content context rather than treating them as brand colors. + ## III. Typography | Role | Family | Weight | @@ -70,3 +69,4 @@ CATARC uses separate large and header lockups. Choose the large logo for brand m - Preference: filled or clean stroke icons - Recommended libraries: `tabler-filled`, `chunk-filled`, or `tabler-outline` - Prefer automotive, certification, testing, dashboard, data, process, and compliance metaphors. Avoid playful or consumer-app icon styling. +- This icon guidance is a presentation convention, not an official CATARC icon token set. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/decks_index.json b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/decks_index.json index 7d1b1a2c..29aefa83 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/decks_index.json +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/decks_index.json @@ -1,32 +1,14 @@ { "中国电信": { - "summary": "China Telecom related briefings, 政企数字化方案, 转型规划, 内部汇报.", + "summary": "中国电信政企数字化、转型规划与内部汇报的克制红灰品牌模板。", "canvas_format": "ppt169", "page_count": 5, "primary_color": "#C00000" }, - "中国电建": { - "summary": "Engineering project reports, technical proposal presentations, business negotiations, corporate promotion, annual summaries.", - "canvas_format": "ppt169", - "page_count": 5, - "primary_color": "#00418D" - }, "中汽研": { - "summary": "Product certification display, evaluation presentations, technology promotion, business visits.", + "summary": "中汽研认证展示、技术交流与业务来访场景的深蓝专业模板。", "canvas_format": "ppt169", "page_count": 5, "primary_color": "#004098" - }, - "招商银行": { - "summary": "交易银行产品介绍、销售收款方案汇报、客户案例拆解、分行培训材料.", - "canvas_format": "ppt169", - "page_count": 5, - "primary_color": "#C8152D" - }, - "重庆大学": { - "summary": "Academic defense, research reports, teaching presentations, scholarly exchange.", - "canvas_format": "ppt169", - "page_count": 5, - "primary_color": "#006BB7" } } diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/01_cover.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/01_cover.svg index 1563b2ef..b14fdaa1 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/01_cover.svg +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/01_cover.svg @@ -1,24 +1,61 @@ - - - - - + + + + + CHINA TELECOM - - - - - - - - - {{TITLE}} - {{SUBTITLE}} - - {{AUTHOR}} - China Telecom Digital Transformation Template - {{DATE}} - - CHINA TELECOM + + + + + + + + + {{TITLE}} + + + {{SUBTITLE}} + + + {{AUTHOR}} + + + {{DATE}} + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/02_chapter.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/02_chapter.svg index e244dbf7..33e8f100 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/02_chapter.svg +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/02_chapter.svg @@ -1,29 +1,61 @@ - - - - + + + + + CHINA TELECOM - {{CHAPTER_NUM}} - {{CHAPTER_TITLE}} - DIGITAL TRANSFORMATION / CHINA TELECOM - - - - - 章节过渡页 - - - - - - - - - - - - - - + + + + + + 章节过渡页 + + + + + + {{CHAPTER_NUM}} + + + {{CHAPTER_TITLE}} + + + {{CHAPTER_SUBTITLE}} + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/02_toc.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/02_toc.svg index c495b5cf..4f2decfb 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/02_toc.svg +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/02_toc.svg @@ -1,49 +1,118 @@ - - + + + + + + + - - - - 目录 - + + 中国电信模板 + TELECOM / GOV-ENTERPRISE + + + 政企汇报 / 转型规划 / 方案呈现 + CHINA TELECOM + + + 1 + + + 2 + + + 3 + + + 4 + - - 中国电信模板 - TELECOM / GOV-ENTERPRISE - - - - 政企汇报 / 转型规划 / 方案呈现 - - - - - CHINA TELECOM TEMPLATE - - - - - 1 - {{TOC_ITEM_1_TITLE}} - - {{TOC_ITEM_1_DESC}} - - - 2 - {{TOC_ITEM_2_TITLE}} - - {{TOC_ITEM_2_DESC}} - - - 3 - {{TOC_ITEM_3_TITLE}} - - {{TOC_ITEM_3_DESC}} - - - 4 - {{TOC_ITEM_4_TITLE}} - - {{TOC_ITEM_4_DESC}} + + {{PAGE_TITLE}} + + + {{TOC_ITEM_1_TITLE}} + + + {{TOC_ITEM_2_TITLE}} + + + {{TOC_ITEM_3_TITLE}} + + + {{TOC_ITEM_4_TITLE}} + + + {{PAGE_NUM}} + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/03_content.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/03_content.svg index 675f5ee5..3452b942 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/03_content.svg +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/03_content.svg @@ -1,22 +1,60 @@ - - + + + + + + + - - - - - {{SECTION_NAME}} - {{PAGE_TITLE}} - - - - {{CONTENT_AREA}} - - - - - - {{SOURCE}} - {{PAGE_NUM}} + + + + + {{SECTION_NAME}} + + + {{PAGE_TITLE}} + + + {{CONTENT_AREA}} + + + {{SOURCE}} + + + {{PAGE_NUM}} + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/04_ending.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/04_ending.svg index 95675141..424645fd 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/04_ending.svg +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/04_ending.svg @@ -1,18 +1,58 @@ - - + + + + + CHINA TELECOM - - {{THANK_YOU}} - {{ENDING_SUBTITLE}} - - {{CONTACT_INFO}} - - - - - - - - {{PAGE_NUM}} + + + + + + + + {{THANK_YOU}} + + + {{ENDING_SUBTITLE}} + + + {{CONTACT_INFO}} + + + {{PAGE_NUM}} + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/design_spec.md index c2a0b0f0..564dc9d0 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/design_spec.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/design_spec.md @@ -1,212 +1,66 @@ --- deck_id: 中国电信 kind: deck -native_structure_mode: template -summary: China Telecom related briefings, 政企数字化方案, 转型规划, 内部汇报. -canvas_format: ppt169 -page_count: 5 +category: brand +summary: 中国电信政企数字化、转型规划与内部汇报的克制红灰品牌模板。 +keywords: [中国电信, 政企, 数字化, 企业汇报] primary_color: "#C00000" +canvas_format: ppt169 +canvas_width: 1280 +canvas_height: 720 +canvas_viewbox: "0 0 1280 720" +source_canvas_width: 1280 +source_canvas_height: 720 +source_viewbox: "0 0 1280 720" +replication_mode: fidelity +native_structure_mode: structured +page_count: 5 --- -# China Telecom Template - Design Specification - -> Suitable for telecom solution proposals, digital transformation briefings, government-enterprise reports, and executive review materials. - ---- +# 中国电信 — Design Specification ## I. Template Overview -| Property | Description | -| --- | --- | -| **Template Name** | `中国电信` | -| **Use Cases** | China Telecom related briefings, 政企数字化方案, 转型规划, 内部汇报 | -| **Design Tone** | Authoritative, structured, restrained, enterprise-government hybrid | -| **Theme Mode** | Light theme (white background + telecom red title bar + silver-gray structural lane + restrained brand imagery) | +- 适用于政企数字化方案、转型规划、内部评审和客户汇报。 +- 视觉基调为白底、通信红结构条、银灰内容承载区与少量城市线稿,强调权威、清晰和克制。 +- 整套模板使用 China Telecom Brand 与 China Telecom Content 两个 Master,并提供五个可直接从 PowerPoint 布局库调用的 Layout。 ---- +## II. Color Scheme -## II. Canvas Specification - -| Property | Value | -| --- | --- | -| **Format** | Standard 16:9 | -| **Dimensions** | 1280 × 720 px | -| **viewBox** | `0 0 1280 720` | -| **Page Margins** | Left/Right 72px, Top 88px, Bottom 56px | -| **Safe Area** | x: 72-1208, y: 88-664 | - ---- - -## III. Color Scheme - -### Primary Colors - -| Role | Value | Notes | +| Role | Color | Application | | --- | --- | --- | -| **Telecom Red** | `#C00000` | Main header blocks, numbering, emphasis | -| **Light Silver Gray** | `#D9D9D9` | Structural lane, chapter ribbon backing | -| **Warm White** | `#FFFFFF` | Main background | -| **Line Gray** | `#CFCFCF` | Divider lines and subtle frames | -| **Graphite** | `#2B2F33` | Primary text | +| Telecom red | #C00000 | 页眉胶囊、编号、分隔线和关键强调 | +| Silver gray | #D9D9D9 | 页眉结构带 | +| Panel gray | #F8FAFC | 内容承载区与品牌卡片 | +| Graphite | #111827 | 标题和关键文字 | +| Muted gray | #6B7280 | 辅助说明与页脚 | +| White | #FFFFFF | Master 背景与反白文字 | -### Secondary Colors +## IV. Signature Design Elements -| Role | Value | Notes | -| --- | --- | --- | -| **Muted Gray** | `#6B7280` | Secondary text and descriptions | -| **Soft Red** | `#E55B5B` | Auxiliary emphasis | -| **Near Black** | `#111827` | Key headings | -| **Skyline Blue** | `#DCEAF8` | Decorative cityline / digital texture | +- 内容页和目录页使用“红色胶囊 + 银灰长带”的页眉结构,右侧保留横向品牌图形。 +- 封面、章节页和结束页复用红色口号、城市线稿与底部红色飘带,但控制在独立品牌卡片中。 +- China Telecom Brand Master 统一承载白底、顶部红线、底部品牌飘带与英文标识;China Telecom Content Master 统一承载红灰页眉、横向品牌标识和页脚分隔线。 +- 内容承载区采用浅灰圆角面板;实际内容由完整 object 占位框承载,不显示提示性虚线。 +- 标题与通用内容保持左对齐;只在品牌图形内部使用居中构图。 ---- +## V. Page Roster -## IV. Typography System +| File | Master | Layout key | PowerPoint picker name | Visual character | Reusable slots | +| --- | --- | --- | --- | --- | --- | +| (01_cover.svg) | China Telecom Brand | cover | Cover | 左侧标题簇、右侧品牌卡片、底部飘带 | 标题、副标题、单位、日期 | +| (02_toc.svg) | China Telecom Content | agenda | Agenda | 左侧品牌说明卡、右侧四行编号目录 | 页面标题、四个目录项、页码 | +| (02_chapter.svg) | China Telecom Brand | section | Section Header | 左侧章节信息、右侧品牌卡片、底部飘带 | 章节号、章节标题、章节副标题 | +| (03_content.svg) | China Telecom Content | content | Title and Content | 红灰页眉与大面积浅灰开放内容区 | 栏目标、页面标题、内容对象、来源、页码 | +| (04_ending.svg) | China Telecom Brand | closing | Closing | 左侧结束语、右侧品牌卡片、底部飘带 | 结束标题、副标题、联系信息、页码 | -### Font Stack +## VI. Assets -`"Microsoft YaHei", "微软雅黑", "PingFang SC", "Source Han Sans SC", Arial, sans-serif` - -### Font Size Hierarchy - -| Level | Usage | Size | Weight | -| --- | --- | --- | --- | -| H1 | Cover title | 42px | Bold | -| H2 | Chapter / content title | 28px | Bold | -| H3 | Section label / TOC item | 20px | Bold | -| P | Body text | 16px | Regular | -| Meta | Subtitle / annotations | 13px | Regular | -| Number | TOC / chapter index | 30px | Bold | - ---- - -## V. Page Structure - -### General Layout - -| Area | Position | Description | -| --- | --- | --- | -| **Logo Area** | x=72, y=36 | Fixed top-left brand logo | -| **Header Ribbon** | y=32 to 96 | Red capsule + gray lane for TOC/content pages | -| **Main Content Area** | y=132 to 618 | Main text/layout body | -| **Visual Sidebar** | x=922 to 1208 | Fixed image-only rail on cover / TOC / chapter / ending pages | -| **Footer Ribbon** | y=548 to 720 | Fixed decorative bottom image area on cover/ending | -| **Footer Meta** | y=650 to 690 | Source / page number / contact info | - -### Structural Rules - -- Cover and ending pages reuse the image-based footer ribbon to preserve the brand atmosphere. -- TOC and content pages use dedicated visual sidebars/cards for imagery, keeping text and images in separate safe zones. -- Chapter pages are cleaner section-divider pages and should not inherit the content-page header ribbon. -- Each page should contain at most one formal logo mark; sidebars should rely on slogan and skyline imagery instead of repeated logo lockups. -- The content page remains open-canvas by default and should not reserve a large fixed sidebar. -- Repeated telecom motifs use one reusable structure family rather than unrelated decorative variants. - ---- - -## VI. Page Types - -### 1. Cover Page (`01_cover.svg`) - -- Top-left fixed logo -- Left-aligned title cluster with red accent rule -- Right-side visual card containing slogan and skyline imagery -- Bottom full-width ribbon background - -### 2. Table of Contents (`02_toc.svg`) - -- Red rounded title capsule + gray structural lane -- Top-right compact logo for page-level brand anchoring -- Left visual card with restrained brand imagery -- Right text list area for up to 4 major sections -- Dotted leaders and right-aligned descriptions - -### 3. Chapter Page (`02_chapter.svg`) - -- Clean section-divider page without the content-page header ribbon -- Top-right compact logo anchored away from the title area -- Large chapter number and title in the left safe zone -- Right-side visual card with fixed imagery and no duplicated large logo -- Footer ribbon used as a restrained anchor - -### 4. Content Page (`03_content.svg`) - -- Red section tab at top-left, gray lane at top-right -- Top-right compact logo for page-level brand anchoring -- Open-canvas content area for flexible charts, tables, and mixed layouts -- Only keep lightweight corner / footer-level brand control -- Footer source and page number - -### 5. Ending Page (`04_ending.svg`) - -- White background -- Left closing statement block -- Right closing visual card with restrained skyline / slogan composition -- Full-width footer ribbon - ---- - -## VII. SVG Page Roster - -| File | Role | Description | -|------|------|-------------| -| `01_cover.svg` | cover | Title slide; brand/project name + presenter + date | -| `02_chapter.svg` | chapter | Chapter divider page (large number + chapter title) | -| `02_toc.svg` | toc | Table of contents listing major sections | -| `03_content.svg` | content | Main content page; body of the deck | -| `04_ending.svg` | ending | Closing/thank-you page | - -## VIII. Layout Modes - -| Mode | Use Cases | +| File | Intended usage | | --- | --- | -| **Title + Open Canvas** | Executive summary, key messages | -| **Two Column** | Solution architecture, comparison | -| **Card Grid** | Capability modules, initiatives | -| **Timeline / Process** | Implementation roadmap | -| **Chart + Notes** | Data dashboards, KPI explanation | - ---- - -## IX. Spacing Specification - -| Element | Value | -| --- | --- | -| Outer margin | 72px | -| Header inner padding | 24px | -| Content block gap | 24px | -| Card padding | 20px | -| Border radius | 18px | -| Title-to-subtitle gap | 18px | -| Text-to-image safety gap | 32px | - ---- - -## X. Placeholder Specification - -| Placeholder | Purpose | Applicable Page | -| --- | --- | --- | -| `{{TITLE}}` | Main title | Cover | -| `{{SUBTITLE}}` | Subtitle | Cover | -| `{{DATE}}` | Date | Cover | -| `{{AUTHOR}}` | Author / organization | Cover | -| `{{CHAPTER_NUM}}` | Chapter number | Chapter | -| `{{CHAPTER_TITLE}}` | Chapter title | Chapter | -| `{{PAGE_TITLE}}` | Page title | Content | -| `{{CONTENT_AREA}}` | Content placeholder | Content | -| `{{SECTION_NAME}}` | Section name | Content | -| `{{SOURCE}}` | Source note | Content | -| `{{PAGE_NUM}}` | Page number | Content, Ending | -| `{{TOC_ITEM_1_TITLE}}` ~ `{{TOC_ITEM_4_TITLE}}` | TOC titles | TOC | -| `{{TOC_ITEM_1_DESC}}` ~ `{{TOC_ITEM_4_DESC}}` | TOC descriptions | TOC | -| `{{THANK_YOU}}` | Closing heading | Ending | -| `{{ENDING_SUBTITLE}}` | Closing subtitle | Ending | -| `{{CONTACT_INFO}}` | Contact information | Ending | - ---- - -## XI. Usage Guide - -1. Reuse `logo.png` and `footer_ribbon.png` as fixed brand assets; `slogan_red.png` and `skyline_bg.png` should be used selectively and only on the cover / ending pages. -2. Keep generated text inside the documented safe areas; only chapter pages use a strong left/right split. -3. Prefer red emphasis only for structure and key figures; do not over-saturate the content area. -4. Reference only assets packaged with this template. +| logo.png | 封面、章节页和结束页品牌标识 | +| header_brand.png | 目录页和内容页横向页眉标识 | +| footer_ribbon.png | 封面、章节页和结束页底部品牌飘带 | +| slogan_red.png | 右侧品牌卡片口号 | +| skyline_bg.png | 右侧品牌卡片城市线稿 | +| top_emblem.png | 保留的备用横向品牌资产 | diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/images/中国水务logo.png b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/images/中国水务logo.png deleted file mode 100644 index 23d4ee76a4e04576bac4dbef8c6bd34914c50024..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57784 zcmY(qb6jQr7cU$q+vennlXbG~n(WE8U6Ur;c1^Zz+qPY|W`5uM+~=Q8owQ$Tuf5h= zpAcDT5jbdUXdoaUI5AN{c_1J##gEV1AisQk#IevQ00Ke;5)c z=2d^ay|KSfNHJ)dw(PZ;k}mI$!7<~)_p*#!#^dx6!6Z@gQHiwG_Ox6us2yxoj16JG)LiN<(af%jP6( zNODIZTpr*i*sw?#v)I2pmA&aIx3lH^r7%fbO35Q@Tb}5*Th)5MT?KL8k#Tm~o55|Z zFP2epU%SoAQwjgRTv6WX7zj@z)>-01B95N`Y2KEW{=3mLW*ZpHefF3;rug2*vc?}=F3ZB_nPZk_> zxIoHXI_6e^Pb-vRS``XdSwZW5-b!T-kj}RMd*5T>K+M?^!fE-U|M!+EEg0>%;A5X= zt@BBnvio)C=tIr3)5gt(CR@syU&~1z=r$4Ik)JP(eIce90nm2P0oNi-+%xbZs1EC+ z;JIE3?Zp53y`N<#usMfWL?Wsn{QAwpCV`t-NF!9Q^);VvVM zJkGWw9vLo>`p5TMABB!Js(N|!VBO$7wdkCGKGLZmCo%{2ISv4bvi?7f8W-xVPx6$Z z&HC2o7rEtnEx&hiTX*VOz)N7>{~l0PSCb7%PC0UK9sC1G>t8qq!Z1rd*;etJ?jB3im@MzVbS5>`M&>u0ec zh~|#QfPLLW5s3R2V(pgiOnXj6C8K(e*yiYA!ftY4Y2T+$P578ApuVes@wXgDbi~7r zHrH92Jnqfi&CL&-o3Bo|8ZfNXWZiz%dVl?f_pN<>wQ3DFaelSWRxz`=xw)x1FR!(^ z>~!rLj{5sx{9T=wzzY8I(&STF$8IFwcwjv5T6NZ=*HTl~E=qjlu4>;9UqSlZT$zSy zn_B+6?QvlIem(8gk-a2_*UHywPa*K<=u~&U#>+XD= z{U0uCeUYHrOJxrKkj4E>=bNUgjf`zqrg&=;Wqf;;)uT?p_$!xg^?X82^6^Ma+^VX*%vwc>?&j_7j78z#JU@eSBJZ8@M&h9&n zssOZsMT!Jdy*w|60&e0=)@^SaWbWGp-w8__`3phfs6mP;A!5%eey%0V0tP7?f@LM< zLq*AUr(>l;eAXfXGmDFA+gFcs1C46~htfPUbx6;&fp|N29TZ-$glV$#IZ;|-!xkEx z8m_Jy>PKrClez>GzpmsmDfOa#MA5pZu5~9jh19U-I+e8*eq`nWyy0qY;vJ5$`6ma3wy@3J^x^J zPhNz-$Eam>a6jkUz$&;8ds3MKJ|=||EJudv;%>!EuX$pw_&F7T4@DE{?4a!kuN?(R zK$l&)YQ&_j)k0u*|3;wu{zQl<5BGQP!w3V^ZZ$20Lyxqa?-5&g1Q*@18WQlp%@mgo z@Thf)z#bOSc2+Qd@GILCmz*|w!e&H7otYhK>g_lNj){8GZQKdFwvZuoRn*> zEh}SIpty0)Sjsy(SCXsSw`Ur!AR-sKTd7&Zz*&%Pf|=uiULp78`RZnaz}~yY=2)Mf zUr?6rjBp>ornuJ3cJe=T)8Qbzq0S_)Xo22WAkxuI;gq7-CRsMKsv@!x!cmvRvup;H|(3g3(6k_&!*J z#k5;(n~Zo=GAnO9S-bQNeL@ob``WF@yO|Da;~oH72;gw_Iz2z%l|?q?g!{nO=%LVu zBRBInfgLjx;!Tr3@i&6Jx>4?3>h}t&nEtaoQ0@hUB6=UhKgXp zH3D2nx+5#~Z|TkZLd&Xti?8}7CzHX#tK+7_E1E)1gvh(z<0eTOH>sXf-DeIb0bAun z?mQl@ez5JucW(A#ar~QD#p9;WEHQWxVgfn)D<3T0eY3) z2_s<)z2&M&a>r3TBf0OCAdvS&_!;u7Pp}G^Qq~3OGlUJCdOhFhQKGtqER{UO^C?B+p&14yt*#U1=N(-34e{4$*RGA3Phktp~w+_G* zw@lZ<7dFdMq8D^-zr zGvnCf%J7SpIdfq-s0@{X59lo2UIEp^OP&#Zp3yH#NbhI??ksnct9OP0LI6ZsI7re! zfRlv8^Bml_jD@AOD-DT3jiu!G<@CC}_wM+*Iu(o^~N9IKi%sFuIvi#U<`?}0D< zN>e{fxTFl(UUm2;A zG^KN>vl}cYyM>XMomcVE9-F)?hfEHkFA^qU^|B z5uOfy=_|#=R5s`ysbqqEta+h0{qc=Zb7cBdVsLB6h^Q+w7QNAUaEXlNiJ zO>_nvI{wK_?pJ1wOS*luZ=#fUVx8g64P6E%Z6$*e`l9{?>^kLTd|*p`Xco4)!O9THe%5!0 zVu}yio0nZpO@Z@Cf}O!mBpB<2`;#`6Q^Q@?HK@U_fN+qSGaEv5VQe5jOOo}+`?$2~ zXM>gBkfpUE)YvVN_-a^TC7$-VS%3YLuRi#075n)-)eYHCI~bhOv=(FRfz9J@V7Xlf zTOQ;KG*Ng*a_sPE;CNK7Q4z5joF-lyiwuapcDS8h5FL;%$v@&zvs7VBFot*T@(ci$ zU#!DGII-3`CyXps5eEEvj))3xTpEJBXEbYjw*pg=Q|7a)>!wCfr&rA>7Wq@e>n4Sh zZQFs2uG3tR{4@ZPVAVYhX7jyV!g?v8bv4pUkUYbg3sfCO02W}A?KXCK^9iy;M?75t zSW)~A@aoYQ^(smI@##LX>cwL$TAW5h2})Ab|EU-?Bs$u^i;7J30+wMKWUhUKfZbz> zaF9&`JA~$gF$k?N`e0L>rY0G!u_Y0%&z7<`4+ z#rj&7Xg&@!)Sa=EEN3#VarHfiO521M_I`P@BOP%0j9$1VsNezZxNJ2?N)M3}F0~`85k0GVrlSm`&@dFB(Hobt z$3$HijpvF1KbZFmGL*$A6~*FhFQ|7>g4+Q5gbET;;2}1wLH_a1IrvyMef2e6&#;0# zqryUTv(R|_zOr?>CjL6)W(pe1d#ssn+b2(prI7xoPedC^656%8-Ng~=xdT2_Sik}L zTFLsq#s|e&NDuH4MNxru_aorZXE+;hgjVoE#I^Nwr`P5uE$T+?gR3-PHJUUfP95V}5Kj#H zH5kB*<9oVuir9#O@3#4B`Jun0ToUlq;jf>LZcNI~>m}8TF8cecL#!-(v%4Z{+(AN= zOGzW|WRK^nuQj<5o?l^uXxmk(bL31d4U^h5h$+A4?wz*D-Ya#{M6KY6%qmjc?&$zBSDvV5zA6;?59B={f;gbu zy5rvS=kTQ0BvBIRFAN6CO`(DGeo^NKGv8@Rdvqk9cE*evCst}f+Jpzkm(0z|o)@0@is{$!`gC7+1E#^`1$G=K}&>%EWNAcVf!$c%g_x&J?MHak@PIcjt8xqu#k2dXEJ8$XvsI zPfN#9@>P*^cYA5oQ4u5dp4yi*n3PwEymOU|qYRX~{C)YuN>W<~OUG|t>%yvzKO~k) zy6zrJ&XyIJg=EU=Ff?Cgnv>N7NT7^ONDV_mow$0Xtu)1i$3g^#`@8I@Haz3G+U~X$ z18wWALBIz->o^huaI--EiTP%2_F$!=Gh4-WgZX7GrxjVk*GV1~m{WBq`ZAzW6Xp&a zrDkmoQ@tWIqKA~$kI;q(G}_29aGt3VmYtH(93zSs<9h09?uw1lkaj2<3jA7gu!HUX z5YlJVnVzS&ZXIzO?`w+P&bPn{hOyzk6|bQEamGJblw3WnC5X4uMVZoB-|VYbIw}(u z)<6fev~CcGMb>9kXKo*3kB3pi+^!m<@mL+p*B2HSO>1)Gq%{bljx0=zjx9}1&(BoH z_l;Vpkv+WY&hj*yi;hQkh7AX8ys88jbQ1R)?4k^Bg#x^6mJH#Q%e2Sc+U+9>I{F{= zVxZ?gaqwpmUXU8Rg%=WZTRc&bJi$RqV3)9r5YtEfGxY|q#^+ia!Lu{;*F52||8kB6 zj8v+*(oE+MtPuqULVN}jPnjVB@B6raVf1(SI zq@2P|?<8FX`dR*<@;iMYti0hp0X83LcApWbpP&h}FZg~WRp4Q8qPSqpFh43eUw&`= zy&o4BfJarY_ZU{26i9~Q1O6%zBL`z6{>zBg8bXK;AMUEb5+qu2u0h(8=db=z4t%juFM8 z9^6)W<7cqEa2oX-=fOk-Ac<~lTb2B_3+)7)K-}7I;i0r~XXHg&ki)NPwm#23Jl@{H zmK#}8JNQ24+EVU|$~9>#gN%Al+uQ0kC$j)U;kgRkv{{Hf~?`p5z ztD!{2Bg%;4pfA5u=aQR)8PH>SLot$U?k^iJae=FosP`|1M?Y(;*)M=IxTo4ExA*vC)1e-yDQwdt`-w13%%hj> z=y-9Vsi2_Mqkk?UUrJ-H%tGQ!eEf&_Ej#PyqYi=?)4ltfu^@R^4%<1MQb4xlag#F4vy7cRAsb~V{m0G zmo?=#(m!YtS8P8eTv(`@NSm0#Re;%nI)oMI=t~Wtn;^i-Ljkkj17|nM*ETEAyWpQt zpjisY`~VW(9hJH*Q7u(wG*;gtV`ivBw=y{CcyIC7ZMNRK_?_=r`#|ow&$kHJBQt;} z6>O>=!W21P9kXNyu+4rY^d2K*UZMEV7&aCaC=_5sc|mT}wI{Ks-A z=(imK2QvJBR@4=w`|(sVWpJGx>4ugv*ga$PDQrS9f93;V9tl`?2?=bErpCPuqQgTs zA6l+ZQob1PdfoI&f@-Nf7q+FxURopB;Oy$X^t--4aeySiK{k_)Ht8&iJZX%{y${d( z;Ncf`Kn$=Cw9rP!z(7w{XSC1BWpu*+U{!CuSvYH4p#ot{aWhM>FjQWBU>R&- zv?)8%L6{)*Mr`MKDxm8XLpq~P-%jLOip4Cirlzf^9)rcYM*>}_t0X5KUvYJ2rR6Sg zZx4?9^prC{b-4`b4x~KNK|I5i3n+LrSC_MCN3u$7^|SCxwBrEouDVB0IWF*^g8b>j zgc2N_phL+dFzZ>jkxRk<_O|LzFxpI{5Bo?N8sUP^0?oI~+$s*Zt1cVKI!fM;WJK{% zhec)1O2&cx=T`yq+wT&`Cx`IsQVHLR!3?)rm^c63(mAQ(^Rb9UxmC)zu*bB5BvbF8kJg{x- zwVM*pum~z-vhj{NI60XT3roh0Cy?^2$&U+zgf7sK9+A&ugMc3?PU}=+l6~Y;h8QGc zRb|O2CX6zd)LGV1E_wNBKyOvlm;x@#GkfA1`CT87{?12bPLTJv7^MdpH;t%C3&eUH z;(LJ3dE=6=wwUvs3TM}_(K`r=9$t8`%i6%P7rTN`C}&k)?M8De7FVb&M$QOpz-wP1`Y0ImAC5#mAqB~T zp&bJbkFLfoPoI+<=J9BRD4FO}H8V_GR=FlNeW9v2`Ewmj`wSoiTb)V-Vh?yZZL)Gt zt1>i={oD^;-`mzR4e`Tb50b9mjY*ECT(c(cL*s5@bBIh>YL&i>>bQm4t-*H(@`eMP z>7-lkc~UpV<3>xN`w1cS#-F9w#a_`K52%`uC)8v>>D^jlmcFS$yhr2MY$vnUHj3~_jtJKRlHk5LNDACkPIei3-iM%x z<_$(V9o}IuaK3Ko)um_p>LD2b(vHYnR@=y0ubKZWl*4-0?^jD zZ~iPdQL+dSl_phpRl7#)Rj&F3!v%yfDVfjo4$`7Bv2M-;*4o7)Wq%qkXc6AUshLpy z1EA&|1d_gL{jimwdW;sUc*lgY?!*Q#Fa%Qk{rAI}Ml%?9lv8;>bYcc$F;>Av1#mf) zRNse>z(}hnsexxz33~;1zQrIOl@KGRob8a}QR!jg%mqF&Ce`2${$Nl5Cw`Tjd0^)O zUE6$vOnQTT(}qUQB{CtjBDDIt-e+)za?o3=O!H^)E9Gg5?NWVh&TZRhT3Nk=Q|Y>8 zi-rDh*=%poYJzdLx6R|qk-`R1z=HQSK6s*GLx`=#w*>4!BzDT|hpAtvDU){Cp(Lm+ z85}2eYrLJy2T4VWZ?h!i(k;((2Zf{RNi{j+mL@~cpA3Hl$H$rvphE^`z6UJNjp)`Z z!qatODa>lc=?5sm1csn&eP4!}j3nw3kySF$>~#j41_ddB23C6i9m+E-{Nm-~OOg#m zKV!fx;WAfL9RZL}jF6w0j!pTMo^YbnDHGgjcXHFl|5y?ly2c6N@LhdiFe;coSCotT zCmb5KOx$8;-r0=yBPS*D#}beh*I^&5N1zR54(GfX7KwA`Hw7u z&){zrh5gz^32*$x^s?H#mdAzkOD_YK2alRadMY#^e3zd_5EkOYSvS&~i40t5kz>!9 zqcX*P<)*m;1}me(bsZDrpHQSqVSB;n`DiD=Eq;77=jFZ!_k*i8a#*w6-x-|w0}0Uq z!ezZ(*fTIK^NmzhDMJ@xQ)!M_WRRtVl=6C<>V|n}r5|D*MeN`wW9qyybHrMvz@kwx zX`b2QaMDQt>ha4i7M0jh2`YM+;sR`(YKw{3KKnRWW||$b>(5kOi^TCm-=R>&2Um%zYi%flE@PpT6K+nFAj!5z?@OT3P+sl63@L!r1 zzOxmJX8`YP{-sT!LWCK->XI1nd^xOJ#9Gq6N~<_WxAY90;AqEO)=rl_YmjM7w%_Lt z0I^pUWLYJHK=LPbJCVv#`bw==G2;ToVLaI)y?lot8t&+t@tG&G{q~+p3)H-UzJ2+e zaB{YcxriUl!!iMWBKNz0Bq_F_!-gX%@W9+P>6tfEYyEP~gHEeMowDVv_z!O159Up4`oBSm zQVOux*@RJPwV0p&sODv{oIngR9vDCx17Uob-W_g`3p8jcReyZG?$Z{Y1Ea+2|Sd@Y-@`zPYjY>ectO%{^)L`Li;_9mW7?eD(B@6ZmAKxqrkj zCIU#g1pYTO{E&&rXV07$X&ef$3z!)aB?*Xc6LBr>nl+5l`pG6unzB90^sx>tTLtm5wv{2$c21)=I5%zfv7I%Q+ zQEfnJob9)O)4;a5Mr*FWg#iQG3;l@UT)S{2`b@(MR%5`s0iVId52Ns^NC~uD@nY~7kCQ+UvZFOUmDv6qDZr)gkIB*-e85Slv1X5OpW(-ZLg!WkkR+iVvmNg zV6vB4-n-yH@d=-{EM{xd3o;k}2VgW&mzj5xso#+)1K#*Qq96_V>(`7<%TJP-#S>Hw zPD9QLGg7)Z^7L%bG9WPdKb`r#jv!4iYpcC`yMa?2TrArmwm155%9V7b4DmOyuIy3x!*93{3hAuBE5L=ApIRW8RfJFKx`;_Z z&K^?8BQ5X5;nvkV;M8J^abO~qDv+J10ybwa%MchkCBzOnO5c7C&n8p=cY`a|_DxiZ zFTx2PA%jSm#jlqhAfF;3E*pjN4?;16V14J`N&`A0vm#plE|QYgwfa$CH6#m-^`QQ_?WEgkM52%TML`1QO9kv>M!eCQ&>)^h)%*%ei$1Y8@ac%m1D<@ikh|-4~Gpzsk8_icjJJ$#Of^2 zz^9CMuA&Jk*ki*@kMZ5QCL5Lj3e;Qgmo~5E=D$yP7U%UEfsTNjeTn<8RD4z ztj$IRd;I|dPIetUlGC*LTifi|#g$w3iY8i*E4Dc%CH2o%Kv@5v{tgnO2#mGw=B0$Y zFIu{iYaQVxB|eTH)%LPO-m!|FkPMSCDK#BV$nYp)D@;)XhMC#1aSL%OEF=xK587jUQkfdI)bOaIyan9v}BgNC@*gIXN+>;W5|O z)|MT9C?`y9MU5_}pP`keChR$j^#&Uc88^4#y$`<^Cpm@n(>mOakBBI@u&~gmtNU|< zX?14OW-6hvT*i&}&FLeng;|zI^u=t?PEr$Bn;XMvvo9#u7jonxN`|322G!-=CH0LzDzza0?r9Wg% zb^mda${Wbi67VZcSuYqxM}}6dtDh&3ZYHLkOexYoNeKNAVG+YXcT@)333S*H7Oyre%t)xT{kQ(LK^9gePjn5COn$);WA z)l=Jh9i?+V_%z}18HVeg9se2Cg%ylt!?>m(hSpE=s7c`)^Fel6{p1+;$~)#gZ}024 z%{vUVi(u-r2ioI)AIPI|&)$8io%XKOqmbTnWtZ37y9nZR+LC9^kAV3$*B`Bp|DTK;G6PQIXY}6^`&b|{0+-0% ztVv@;fdU38y?RVKT=&$zdu6#t>V<29DOUOoU)^tw*B}F7{`sM5#FcAqVlD*i4!E<9 zzY~8$KVO&nl|@KPp4dVn2N&G+CI4`hhSl$0qL-0ABPJD^ylXhH3`<)hue!s+n7#d= z#T|%R&s;w;6i!hBy>G-!wVx9!FcwWSf~~cmP!F!N^JKGPeRzNnfU7Y&JfK&)FQh3- zEq;P}*e_(p^dAi%sSQwvftl*f0&-xYl$1$lq%&l&V z0(#^_I4_U&iKwb}L+ZJ7KkBKLuD0fq(NvNzyP#7Oj@yO)cdUVcT#Ia6sd%_Ip%FU) zX69tF>;(O~6&^-Wqy`$Z?OTP&~z9ClGYQKYQwS$He zK-@f2^zrUo5+p3#&0ccYp0xLyVMbm`%wM`jdiD1863Cv_53Czwdr2%lV=d9dLj_X1 ze31yfo1I*P-?GICJ%H1GB_j6uSKt5=#1ipX=>oQ=(ft;(c?gubSdj6ix@=r3;?lz& zH?$+#6&V_@S**X!owy(bX*?dmii!*EaF}sBGG`vkUj}ZE zQ(u7{Fak0gpbi)@)g22PW|D&kTyTj?qq=~wp!6<0dy38=WVnLt!#rO^X1IURUcKkS zU%ZELH(W1y=$C2tso;7fd+RS)@8Wg2N<&_LBYB0;eUZ7t^X{#A(B5@;Pn>^`AA{tsXV^;Q}8B1A>o={B4mI&()2_-{q>t*wX|al_pz{;_~M&g@;c6zoF?& z5G0D8D(XHP^_KjiwkVVjz{}k{~3Blzo!hcat}P)U&!HkM%Jj;#{espiX(dKk(;{&scW7PrWsWeTG4%24-RwbYUwQdW#-}l0krp#)7(}r zC}iT}LZ|rLBitsCycg)ITwXuMkqIDiy{(CKPYI?*Dn_cv5@73kLXsm4<&d7#(nub zA?u8OynL^n>|zV1eN51o@MQOpk&)I@!E4DFHE=iZ27>>1sOG-g81t|c)Bn*@t~ik= z&)}hFSg2d%x;4t?fxqPGbO;FV#3zt|^1XzZsfw;=3%`Vhb9GK4ah&~eWfD$d3+*EL z`|O1ZZS+M%?0qBxKSHL-EDrVcPUM}mS1AuICMcqQg$tq%{0|hIZ&UIqS1B3lT#o-~ z0j}yAR-*hWF_Se_Mbp*?mgeS?qLZPB3YtGq_;Qoq5IB?;4rN5mT#30Ffd;-)nV{GK zQ-;p0E|BMO>>?SLq1z~Z9f?84-El_*<{u@Z3$ATsgABC6uVh)EVUtV7-yrkYxB1Sx7ur8bojw0je z^?Uhrn9`SsELl&Rapd}p_$GV)0_i+rSwUS+`3ATTq0Ya74l1ze8A#V7w+=CRrJ`{S8PT}7g#tNGZrg*$MRQ+UTZQd?E?K0hK(T}eCon+X3DqT@I^M zsnKrv{?Dzj}Dvh8VvlB@ci-xNKxqulW37!Y}f zaasEo@|)*{@r*F4Gxq+rS!}u&h*q6cBpabAklWKOps#j*TXOQ!D zSJy|L#*!;e(is4~63gpZ6RZT8@S;#ML~={9U|C%>u{OT5ET+<$hxtZejb5@fDyCC+ z0dJcC{*#y!sX-J>{I5BQ8bFE5K3pcSprK_hYW|cs#*qv52=iA&DlfQmf}pMQAtT`- z^M-h%Vf(3w7sQ^^=E8P&7^?N{yowl$Ik<7V3dTVW5lz_%7mV7#T16@*6u&uOpJB+t z11alppso+C4sajQx7}kfdC8>T1P8Y+5>ehU z*0wqS*(+EHci`*!`o|1IPXYmN)JTt@F?w6-lh%K|?J> zFc_bAvjo|vvlI5`&t&hyFoZQNJspL(V@zf2MT#EGIL{Qv7jC^*hBO43>>qQYS$bi_ z&r?wzHUlRim)t!M@Tbp|hD+1{Eeu_QvWu{c1a-@&PMFY|~*o z;;dJeub1Id@fO2X{a_?ht@fC;99O5l41Gka{0;FbE6qrVqHA7oKON@}SXMj0WG9Gz z_Z)qC0-p2w-da6@_?C%L*+wLRUa8zCYA*3yt*)F_7ov zi%NfKge-kY`CKOfgd43+TONV8a)I;Y3lK5HyJmfZ%SgKIed0+~;($lCbx$6r3JenY0l%+@CSy62E5>+M-Eg^*Iqmw&x6mHc(d zY91=mXMUlrSMIEYzHOAo=RBzI72l?P6ut_J>^tXw&iOdbNJ{C>oh^h zanOUOND9~Kv;@-++|%#qTclj@OIC@6oAOWLo)@Xm;zSUI!6ESD6x7c=@^ z^ypq&q8D@vNQkiDYwULK|5yz`hXt${`u1jJ8N*{ho>$|Bk;^LG31>Ak2ACIY^*9!vWdH>k9G2liKwRgN<=mkWyRZA4@i+GK|73LL&Jr^^cu`JvA^lIH( z`{HM$IpiX6Zrt)ynh8%kW_5IQoFmLS?eGEZeR_Hdq1;d;(qxl#D^J`+COKkt)bc#i zd?6u1@7cAv(st{tZxt}zlQ6vtZ>k7u@-jAG!0t;=gsGz2?c8l~))tj~-|cN_N_5hS zV|?{-@7w+VDDAv3;4$&_!)2IZwzk3{$miY>cbzQ|-8Kh1U=#VKe8Gi%U6JFt zP523+xvJOK@C^T;iRLX*c{$sI&8uAq7v5NpfO=El-_9DY-my!;;WwIYx(~4roeVQLV=4 zCsn`>i%fy|+sGri*V{^aSF%yZ%aP2i}#Z0iq z!T0ps*cr@7cz7r>hTA3~7rujojcns3pxqat_Bww{4QQX^f(TMJftnhuD0*Y0m6SHcb_gL6$r4BL-Fs;Ojs;)4bq&tN;re`LA^_I@ZaeY8D1}-%s4BqlSpMQ3wq$a2W_fN8YLU z0(Yfb?J?^+rhoQT0AEk3*oNRi1MwUNgUCX;Z-;#qrfH{A$pab4`nRZ4 zF?yICBU>2mK(ng={@+ZB<$6LcxY=d9S)vofAN}9(1!VK$R!GOT8ehw8upTf8E9O{y zhK%iGI*Q6I+Uf-ol))Ej-cnxu5ugNf&fPLD{$K^PEJK59cf2OL4|tys5Ch1KJ@2=U zb^e!iptlNSU2sD=vI}e}UJ2k9e58R1%m4flFIVOgpVvqJc5uR}U zjOLmlq_|W=5taO;bkerd@|^NmqCaLBQ%2GM)ZLXHTCz~UfREE}y!RqihI zX^0mi1GhK}&$*h9jPl*-Bk^B5B++hV1a7_xbMo`Z&|3ZeEl?36UF}%-XM6nq`(|_N z2aPOlv4L9x2aAUS=G)XEidPYOWs;M7`tYM%gi&KD`+*il1iwH<9jGCBgrlwTkY5QR zHzmW0zLYlI;Iw)Bfc+`OM6wyuc+N_ORzXqdx2_U=$0bvu-xL~0fP-5s(8i#)W3Pxj zR7_(0KtW{YhV$lIXI&xqNuor|@ba3pOp0}-8uJsgvz3-+8X9IF=SY(%hNo%J z9nDp9Epb@DK)iaWgo=k=%@xi&5X-aN(V||b-`&NZ_4R#70q{6I)ou?Sb6P777=B8x zyqN!@c1D1XdH%|x9>6Iq((rCZ*MB_Uo#tz#zKL>61GL+t>L~k1Rb7zE}&3O(wN4qzo#V_mQB{; zcFJF{JpcJr-T)}z=jw5S(;^=|JRIs$^W3!lMZ~T5E7Cl5+(jfa*>=!Qi3#WTVojz1 zoe|Ll<6@Ih!k*RvE>GYICztTe`hzccyEJG};3C#0I`~!sG~B_O)`f_%ALLma&|!qM zphETKEWz=pk&1CO2%T+tH|DD-|Ef8)=-v7LUBb4r`m-U{$##AXST#TAI0w zOgm#vLCde}1)*(^c31Ok2cX_3AeC_~fvJd4RSC55!^?uX<|mpId-&xt#HXMuud@^@ zi_=R@wFN~*={l`W2%K+_|D9(b5Y(}z_xm^yC-_w)lwBbiv)AYgJ%z+oY0H&8ENrJf zf!=CRHcr>i=j8F0n!OQlLc7=oJTU)XIY7?8-iMP=?Xw4z*;b+9;Nxt^iZeC-Zd^i; zEst3F0qnWS6KmqFDxqi)p(}r&{q2Rg1OY?*_@px+eTyCY#Q6Pt;S~Kq)8gvb{aIc&3C2!{@$_oAF$8%QN~yYS?js=%zMu3`b;$= z>ojHbi2e6t$^R>dl{~WKj!Y2o;xEc41hu1S@y|s2Q53y8WNONAtBIsX^1vqO1AEj# zOa0#N`k-1?z5-PCKI-LkeHi)wCIv4H!OIK270xY`EkQRsM=6NtIe~>Sr$iKMXu|dW zu@?08Z+?Kh<*z?llu3s_mAJ#a7?Ph97Ltf~0gzN*Bp@55QFxxE(#$I{#ejU_$Yf1f zP;>_Z7$_+J#fe=&6ZY1_89h;QLi6_tPww8@5a)?}b2(^y>Ua4Bap-myycEPEH!M%7UFtRIdGk z5%1kW;PZiS4YI>o_iVBI8)}adhqNX&A5Bb5uy*OcU{Vs*7=VN0Y0O8ry{WB_BK9Nm zPrRZ)gi3u1x%fCoprO4${3$y_B-r(hR`+eV5^(y6RA}4T=%NGbB$U$N0ZQl* zeo|w^Z{_7_Pc)CrpR&NqVq#)ePH{P^a?Tf7PAahP<`dUbF!+1vBXwH-7|6@Bp6dJ% zQGrUvfu3n_x%6ff@~?By^O_i>vV>Bw+KmUkp3>-cgaH_wBVT$8KC9_!A5T^t9{SIx ze+ok&QKJKBwb~v-EJ+TQ{y=m*H>Lf57;d|sk!mK%MSj*Pt&bG!{yv~l63CEc0*_b! zvjg(&n^hAGBGh*l0HVN|^zk?vlg!|pW7`Bq8NRW`o=JU41MGxrxB6mAOI>n--V`fv z%z&GU&Ec`TyPMbd0(ztDM| zNY{#%F3g&bX8oo@OOz<|-)pQN@x@#9Gc-G31Ttsk7~Q1_u7x#n3mTWiwocI*8a~)i zg+nGeFMsz(f*|l=n&+@f+q%7c;o}lPJ`Xds=#)XmMLU&Ri8Af+|5wjSLG!nAb&W`t z$%@>T;9He*ro`@ zr>k7aT%w+?!7IQ943N65m@?eh@&K+aKcST*S1KwvfG#BrVrm_nj~#*yu@Gt0yBkO| zn@94n|4*<+^j}7TRo*7 z<#>6`GWx+-0qZKsFe^%`>HvVj_jV9oVOXf{k9G&Vst{Xd1E|TM_kZy%S+E~>xOZ`V z{S8~>{S%xjD(Yc*6nmH9M`;-0)!my<1dR|gd5vT#J*jw?mLjoQc3PxHd~-MqWh(iV z3k{reG7A~eSF5CC^k??>euLR|6EH?2cBa<$JCWJupV0Z0LyZ5ghoe<5-2%-h>j7~) z|D*AQ{`Q|7Bc|&+8+Nl1D%!Xe*-SbKw&2L6ru(5PA$ERMb&r{9v&uvHq|xa4ZuOfR zhp3`0m`BhbcL(=`nehCt=9+Bu+vzI1pY*4wfom=e8FX5*;PBAG5iqoyHrsDh2%-LC zD`V;SG{xPgG04HnOp4-Uxu1|G3mAEhlvNU|HNxn=fJFD0$*!CX+e2}kZq21P*VY>0 zQ~z}>*3d4|j3(0Jnvwd_X9ClknGTk)wDqv5XjO2~I{tna>M$f0A>BRirRC0INn!7d%pUc&}p+MnB+LP7)Kk}&VKsP@2dcHRa91LF;e z_$}2s3kfus0)V+Wv*|mXp4O17Z?uRXWC#>uBs^+qa4RGp0dV0HKfz@pBnj2ZA??j+ zz*p7fgIhzfiR&rkqX%{p>>g49KG+Q1?m&MO!LE`Cp&dFYk3_HUoQ^m0%b)kEuSjr- zEpmO1kp?X<*4E(&;Opg)oBkf>3ZJ2OA`cr%tBSUNWm7M+WOV0KRx4DbiqHMQ!$)a~ zv*cQkcVwH%fH#9Zu8WUs@^?PdVd(VW?pV+Dx7dEo>RopEKdSaJ%Hz!wYXYk0ox}Poci|b;t*c(1R zp|7xUhde)ws%Lvd=z}G)DCpi2ZeCcb$_>xrym+#{5$ywkGY%O;N|k&2uf24;kNXc$ zS|biVR{~m#?91F7>#(X}?w_0!RnO#%bs?dkYf1{(EjBkjHm>)!T9B`_s`-Wyw{7BS zj&Isj>m3qing@Bb2&O8FWzk**yvy`bl>XBhRnY*duuL-#xFN>M5=4LH&)J(&*c4LB zEx$Q8GL-d=W7LOVRVrr(>E5xWeC}Pp@^h%h?SFjf_WFEHt&2H1uzt^gsLzM5dLQNH z4lzYLx)WR|XlQIA1ulYwccJI&!)NW~yHf6kE&X!DK1!GPf5SCQ8N zq<{e}iB_Uoq=*)+ps@;w{C%b5u{)S0{#mZ)vPRN5p+#r5zfE|6e#PuGQ*4BMA;kTY z=Uz8S5#7<1v-yNhX+;GOgXLm&|97^QqRtFi6%gzVX0L zE9&t^u+3IxYM)^FLQ3I*#yZ+vVO)N86u1OOK`C93T>LCK7o! zC2Ec6q8ozG7FkU0uHW+|OH`Q9B&MgDk9P7!lc)R5B9~2?YVp~V{l4{mkD<-&zv{XQ zV8(ZMRz_2$$!ACBX8|#4_{uq!r=&2%g)TrAVEBWMEZ#R#&8h`FNVri)GSul~U0q3R z0Gd_wSoQ<`XY3DeH1@>AT$GT7&KG` zG*ck)Nj~1!8m^6I6cR+PsO|Mf+}t@8{w!;L296POdu$fz$egU`xOgTunIJWMxkClO zv;9aU^)}iM3Tc>rftOFF-^`I2`bG%6_1CZ2vN@-~KwBe<*|Sis0b;M0P9&uzt2w;B ztbk3EVg;;U_Fu!CXM}^2H`x9TRWCw@u?LtI5s>L70I_;Biz9p{(rdu9TwT;iV&a*V&24=@gvMkL-&XM zT3C>e>{rW%qDFDtIM@crvbG; zR0ekomqZI#&|}v51@cI?>2ocTdB7wMCKLHM5>)dr?qr*vSd1AUue_6Rz!1Pd4J4wy zLaW-4Lp^~2PR4#$cU23n*^;Fo0!H#>Hq|~$lu*A@2nD$Kd*KmMu6}c`G~nu4lL^_4 zc;6R066G==PUt&$Xj9T#A8I+05n53pWiH3eYT9fAu%|gl#^bCpa&s>u_C=;>e+B?A zVqYw9kF{6AXuq;xw3Owqd@L>g@BRC|B)2Uwsi|f%W!J}H$7<+nV^iD_OK=vZs3cj>Ie5qL=XEqNsIa-ZwSOnJ}&m zd)ihATC;1zGU<7>fPWU-;mjn6X2mIB>0gnyhY(@2ogb~KXSBubf%x}w!3N(FCfz)y ztc=2S{~kJmwK<@mo>5X&5nNTDbp{ZP0Sq+zU9Bo9)SP_7_tFq4da0xM`jLyMWCzzN zPrJN01_gf6psH0!1i@thDa5oG4~{}{#&U5$uTweMmV&>Omg)kKEFpH756_=ewkut+ z;KZ#*p?B^O_X~8H$S-*qI`TKAIUqu0pf+rLOSiCZ=B{uztdME3e9N|1kF?Q z#Yr-8L6J|;9A+sD#TQbEGxDfgc%}^8eNiy?;4`rY9`zu$ae|Inp%Y*x9l)&$q+^U- zeg6CMuapAU=|iYks$?`iW59yIJ^i^T2bBG z4T?#=j#40Fh!QRD`w|Itogb$q!%s{5dh9i?>q@+~wzgCnW`jhyRu!RLn$TW8=mHk> z3`>r1bcnq-nJbJ)on>HwJX#SvQn7Rl{1ry^^prrh0G2-yg58WH*2r8Qz)~h{UjV9_ zYc3}XSh8`6qK49P0Ou`MxS=?lBXRT{M$L2uEHIV_jw^-t-R;v6>HLq#`H4iq?oO4_ z6Moc<3IEYTP%hFS&Us4F{;lxdQvE_*1*hbSitq4GjPNa%pE3***cn||Lx=EPKu>sH)KYf9?!Ga6u)hnW0Oc*}_ zSjv{0qTt;xu2p5FoTVljE-X`=bEl5|bbbH0p`S>npb9@wd!k!rO;qd&t7&}!i%rO3 zT=F5HT;e4ocAp7%Js{Q3;O4E^wJFh<&DkKK7z)WMmchECko{S$6$IUTl0$S7rkP z1Klfo#(xNBRHqITuK|}>?hEqfR}`Ki>fL)Q6>b$Yr_wn5`%%Ktuk4$4)%JUPUWC=ZGoWt~%ZgRk_=7`~G9RYYlNm$ESkp zAqMO!CKRtQk>Qv44jzc(6;-dQ1mrk|0)bo;nl$( z`;7x~2&)eRO1#B7hCUgtrL~W)l%4}3Rhf`N$;8sWC+#rgIhaU=QGIa;s`!wE~(rw|JP{hJtz$!M1?*+>8C?TAtCmbnR%keodEe z)}o&IJ@wb$j-(ZfCX&s-4&Z6K)M?+`8)2)QqZZ|^e}@S}9?G~aicNnye?^P^f$+^L zbELlBW`ZniNsD^Vk3|OKn=hUH31A0uloX`xwML2k@a(K={rAesUU7x3O7kyb2SV_l zUWD>H1;}GADAK9kl@D?vTH4f;c3= zyaLc$6*DQ0m~lp(5E^NfBkcwZUhD2){H*o*!$Su8+_g{f9f$$=&#%v<3#6a?!#3q&-?4DjNm z3F8)Bmt$Wp5XPHprm9htYz*n+AC24U3X&AMN^ic+2@=a(=&~HpLGy3j0G<$E7)v$`v553p>X` zMa}g&tlynqWJ2NVX*DwZCYvZ$3weELK-P&Q?? zj3zJaq4(asR8(fU<|kmUYRqYZ&!lVVYkZKc<+#c**Bzdkc*2PC#IuoL_-J6!4f1mWjS>km14Q)4E@a*Iy z=$laV>)~<@y&g|?H9B!hy;ffL5g}98u`mmL*^}WOyU;pJ>9==r(=+Agt0)&JuG)ay zc~&gHU|*;l{-{_mixIK$t%2w-f%aRQI2O+_>PSi~aMw^A$heP&`%A)8}7SV;dt>GwIDNJXjs2A~ynA$iMtIQjGYcJeUTe;?{ zeiB=`+ko!F$g?(EGdGn-sj-P-)>G(~U*ddQRlz&YsjOfb2F2!-GdNA7A_HmJU z`h+O&U%5LTkV?b}@3#v-VppqD828C#3KG;kz97ofx-;;Orchrso3eD3BTK41q1+a? zcKVx2*8l-rBo2@5*34FfDli(F{{Ud+m%{W#xlhLAA`QR{okUVg5ynZ0DJD|e5O0k9 za^d3|pN-)qRMK;eaUSOp-9%?_P}n|jqn_vWh3fHAqT6mxzq>2*`s_%ecF)dpTYd3( zi!sk9p?2jpblLLFy>9&~%qwy?eHT9%x^} zT4OjOM4`lPdN>(xs0|F6OTgD0x+d>!9EuF9UD;Z;RoJUvmk>~oUiWfzx)CknjkM^k zivw+^{S++vH^U*gOq!b(vIxLsHiQ&jHebj@(}|A9Ya8wAE`F#If3B`^x3gpXzz!U$ z7!rxUG`L>If}eTz9oUY1M;9=rNt-|0BQ%qKv>jb>Ie!!1>^$dvvt)|V zAKSSOyuH0eg+jn%#8tq~;8v6s@rr&>;hV^@h2w>SBhjCH`4KD$*;9f=ZEPIM%RT*D zr{GSNuv^am%wVw75Ojs+T)ybk*zcvM|Ei71XK|qn3k!?VAlb&{d~tq0YqBshaO>64 z?}S3U1f3`u>w5VkOrkU{0ghbO?jJ7`T5}y>5n{FkcX6kp2%hpzIMOrAH7D;zXQN2Ct^BS>q4Q<-Tff+k#h(~Ry_|;~M6c*$d}OWeo{*V~M=bP3U|uQsep^%I zmBo7*N>sMsxReEhS7TQbS5sFBbxJ$OV#0%R<@NRTW)kM+%98`d6LeX0s}pc+=TXJ8 z_fHyxH+G1%OiL6b-dnZmex9W#<0j7$^6cPPRzV5 zg195o6Qp5aW8>g3o5QSkM#nBL7DXOrQwFbM_Q zk+1Abap`@xKM;)tsmsx5hw19z?KRLdaZmI&DA-LmUe_eh($mVGkX8za*SsjGZE7n2 zHh=plY?$#dXVdo(>i5h`q>r4;5V^UCcEtqp6KqKoZhjS#k;`P zwRg0xZ{c)?G#5+%Nt32u3dV; z?I2pr^&)_&v~l!h%V0WW2D?=0Pg6LD_6;XX^k+rBtq@$h1cWw- zwUS-j9?W6nLtdpXk#fWK3rXRalZC|qaV;09k?89^3!PC2-X#Yd(_nOJ_tjTjs!23Y zT13*lqTRAxYk6g5Z=g@~7H@YP=M*SQG0Tu`aPJMlZE|V4v07g8+HL{@V%Jv|T%_eC zM)6lyR$LI9I5vFsUIH(I`J=sZ)DKaiH3>}s_ld6YuFwYh=N6&4{#FP~1Y7BksN}ZJEKoufO zHwTM9q6B349T1WHEd%I?cV#bPt9fAC4Q*a^BhjM*#x3!c`r+Cb5e?k^nb&wvq(w=g zSyVLiDg1m5EK*_5lIIRmDlAx42(y#gLrVyigVKWGwhT)wb@PjlO;P zWHHQJa&zm`cl`z+(UZmhdHL~mECA~PYZZkjO%HdLZJ)58To{6KK(!xZPEK@lJ_xO% ze4;qwNvhB-guP7|cbyyo)_zMv&sk$#abS>+f$y3Xh@c%ZVNYJ*YyA#@fJok$8^FcpIa*GXNcZfc-$6an}4ConUr>}{Yn~anU;f_hPn2I8SRuc z_j{X3l3jt_@C{tR-?*U5frt@enwN&P!X$;X{jsn+LZwoeyre}SM_S~!7%AhS@Z^CY>pKbD= zswAIm^iddSWVnY@9#}o$?IeoBTx#Ke*vRJhHnOv`i`cK0LXK#R+US1(?t8S>;NK*E z?exs*-tNPdN$TBc&~g(vj>yPx8I!Rw2%ZeKpO{E7`Vjh%n%<%ezb#FWL)3d)Q=NnN zq5J}O6I4C-pCw3@a-I+y(%Is4UJW0&RypCXO{Xwv;vmdFLu5MHZsF%vBnTP;i*iIX zU561u?2YzYs-$p)*67Tl2417Z3Wj|5yy|#ya&uqj_Njt-sp7l|rmyvR-LJahl}qHN z(;eoqmD={e8k%$ZjTDW}v+TO0lB{VZNl{D_KaE#S9c849S2VST5L@ zGU#2YI=8^qspMDX>5R0Hb`+PNfM4hyn7$iQmmIYxPWCycuyc%=@?2ZH*ZFA{^4Af{ zaQYBC6o5yXU@z^g_g~OuKTS?o>SIx4bW9-qs{;I}FNvQ=_s3?P-FH%*=$Ks^}NL+4HD8cVIY!}!zR?jckUzd?6iTXq2@NvI6 zBjwykN&w8DM=NENB$NOw2;CYWnAe|G<+ z3RSdZ==4f8sTIjH6Rw)N*@0KHvwB@9$KtU@yvsVS_~hqL1H59-2uy{&pC%)^%nEq( zrYItvwu&P9F>SGM_-^i|rVff2q^7+F5S-}1jX>#^GqT z*F|!bMmA0PHk7^Q&tyRFR)Qvq0D3lYc!cZeC>5@wSr6s%lbHCTEWlzBbrsxY4Rc0G z%+Ao=s6v0Pl3*?`vK@&SdmKenS)Q{n7PuA>VAnA{00C~{5N6@jG&hCB4BrMJaXbGh zlhUU=-xqUmNuZ27Vccy02!s;M*rzODjRS^nCl|`-;8ztTg^#<-m-{wDvnA}1kRsqF zWS-w9uY`Ae(0Wcnm4^+GyEwRCVX-Fm!UNBc#o!Kr4hu z%Yrh2qwZ~PNH#9GNccwlk)QeSCHc+bZGIlwUCPDCM;2;~kjrTVVrTFPPHB46QRW=P zl+Yz&`o!a-TJ&ASJyN21X&!jV5D=2tTe|r-}2)=7)W*Ffcikbv2lCEOrTj_ zGjsQ_^8i9-xwiO;B2w)wU=fm~1%v)6+ll1hMGl?m$Cap*c}2_1jCmN>VlaXlRZ?g& zG7agh?M!N4cct7W4r>fet7+|6n+{$wt6`975dCxQx1iCsC`%&Lqo^`toZk>thM|{O z7$*^8otZaUlBySb364*)gSRME^zs3|4EgVxZEr)7Ck0@evUBs%*KS2h7G{_{se>xF z?#^|c2UmA1Vax3=?8wr+bAP#N)R*_FXFG6pon9yQ8ft5b)ErW2 z#X>#QIeS3N^KU9l7!Ppp5qy86qn_qafv))9uXDGub>m-ao~fL8p~WHM=hvDrR=)5f zZh-Fiak}FoSJsD;(-Qah7`S8WT2b-WjZCL-ep4rFI!KK znHFBT7o+ck*27>FOHnpHNhkj`=+HaDbcgny?t@c-_?TD=-X>$DYP%Z_l@d+seMH>! zdEA|H4Af*I!SKjCibB@*`TO+o+*g6gcRZ5k=8Z|=B?gjLl{WqM<5+SZ65%7NvL74o z6XCN(%ajs8(||D+6TjG{Z@L0?^2`udwcPbLYdgyGyemTptIGrA9%nS#{jo?)P4>GA z?g|DsEW7`-I3Fbg5CUa8etF6&X=A^`2|0Ei;VwBoeCi@i)OvjsBVf-08d8Bb#^d2` zI4_k+aZRWbX=%YnE){ThwVTQtQ#kv~&Y7?anvW9WC;z9X%Wxol3aOWGQf_3U9`qGY z#Kp)>Uvr#sw*QX~7cpc1{w5=jX?3FSfcf3VVAw|0_mEvvW)Hng^6!dtw|Q7Kg}Ewn z17e0TNv@hcdchIN1?P%6ok6a?yR1*dNPO^LI)@|Wn_{A5$P1?Gq!btYPcF7;!Ot0Y zDWJPtL0+@n?kApZTdtq)Q!}M`onMFkF52FkTTqQ`yU7e#FwxCZa&c157w6hPyMDIL)wjT2WhFtH))n~^* z6XtrqKz_Tt;yH(vHJZM*XADA8T~2)Bu!$3Oa-D1PB&?mVzZDl#Zs?G$LP<&H(Z-bh zEnjNS=+J)b*33Z2R#7{!H^@gOVLnC>S-Dc`2Y{T0r^vL0^Aty|GDBL2vJzCyvzV^- zbzfqJQ{VKsm{mlY=55u-BV1Y6??K5O-x$>w?l8>M6_lihd^gZ9wzzBzS~P~K0bwN{ zCyn-(#IgcD%6zSgT{H3w&0!bl4iwbjpb|;wcp1sjQ@FQ)@vTU=LNyaJS%@Y~-Otz)gizr=Zjc*2;Hu zq?1V4r|YWIReg{BzVN`%(2$swR23OQjB=7{eWb@3N`Ag}J$W$la5U!U~G>MJnpU5-$9H;XNq;xn+z zBKb5QdAN9PbokSe9jw31vuD22`)KIm;#xv3%j5Rqa{A}^x(J1Qc3q?5flRH(PU}9D z*|HWQ-i7n*>|@daRq#7R!F?)fB$6+3ifgT=nLMZZZ-MCY?a;|gE@?jL9jW);&VPkR z9q1%SZc?YxuwPwLp^EhCHZiTvHfgd z-)I<6Vv2{c-FzYYg*)1uU{}U4L7n^Ufk{&yGMo2=f{u5stoNV(qnKdaIB!dy_p*D-_XU(b>*8^X zSzN}jvqyaK+5gK0d{*<}%VH&{%5m=2S3Dr}n1272jJkgt+ul5wdF@MOw-JlXmoEH7 z1k7TRx0^xCVqx^lgUI8j_=|NyY-W%=Ai}+a=)LKl+`fz9-mA)QgY%s2Nh)U3sLv=7 zFaoEpP4oos*LnE$##P*)lsnYxVoECOCZg)4wb+dgEq|?gzY%{R`Wpp85}jMr;mfC- z;dey;x7x55f0#Gh9`opA@+QVNh4$yzv3=X_U+-%??_m3v`t5~x)5IMD!bfx&{zj4S zdOg`&)TvMYOC78#V`wo%354#UozyIEzTD>>qr4BAS~Iq~g5yh@o15sTw0oAjW`a|^ zL^XKOL99S3KG5=mJW3`i2WC_)uXEWY>TWf!P!q_2f5N-C{Q=w@Il?s5MgjNA!;o~Y zWpM_}wM-Wm#c*g*jDG?akTm7o&r&lygmNB0`Vh8yaW6>^!(_}UQB6} z2ldN|6w;RBZG3L6tO0F=H4{D#rs92igd+p%?Rc2Cn&We4G|7p|CE1P4*AqbA>;{+p z*7#r4Aux#i%AS#Bv=z>c8?pZy)Q4pkk(wG<_9E>Bd2%1mUp?Dze#Yy3)bc@@HDf1e z=6oKcuqNFlm;L5$=x*e3%`d>n$a*#N=g%KZ$TZiK(3I4alCXSr*#0ehObIKf&jleQ z{5YPzlrb0OeP<9?)ITew<2)=LWrFV0QU|tJp1Ym=jDW$2&MZhi9;bZdkhVIC1 z$SkLg3m9Knr&LIN_h*IzPnJtI0@}Rr3Gm!0MmiT$v*AM7AIdQfsOzXCxEKW{in>$Y=*;H(4xNMd z$Pp@^`7|p+A^s-qViGj@^Vm>TtV9#faF8iud>800qyPW^{C__L6IWqHR$uT(Tx>fA z+fpkNCsuY8 zZ{_4PbeAZ_&g1m7IsK;=Y=Mh|BAm;5yw>sS*OR5Li@u>QkONV9>P8~-7G%58tj*9_ zSc!i*d~9MQ^y^JZdWjHglYBf0hv2WvwBd~kzF=Oem=ix2t~7GVkloM_fDIIgQp71+ zK@R~6F`U{3Dbd;-5cXV6j+4Uq0B89Bxo!Sl*mL2KH8iPPl1=4mKL1Tj(W3a1SUDX7 z?SMNoZzK@(%e&D?KT#*n`_O=$Lrj456an^Ui9&2Wp1hR_@R9Rle!r65&=>*y&=I5= z>wBzh-|5 zPU(D?y`=16;Vb)%qo*BhRGzhDL-JG6D&1!-R8HV|D{u=gGkf6sVZFvIidiXR?_ZkI z2k=j@h6nh|HTc1Ww>=+g5UBoAmiz=|$2l|c{Nj=e-gYbMf9y|#4Y_bOgf^tIUd8`!3s}} zHtiph6oN=$jWIZ+hjHrxJoj!zUZx^R$0jLHSawHN!58%}CuiZpHMgJ0px(>sG|8xe zfPkYHPtC7g$@F*udc-!PxZXU-3nq+ybCEE%ML%Y@@g)ux2Lc=;O0fAK)bisX!9<2e zNRH$TdjC6Dn6p|8)L9Ey`<=|hYk|Prx`Iz}XyZiC~-ELuX6!pHUEz=TaoNimWz%((RuTqtN z*QsI^>kla_sXe_m-&L;pcPIQ8Gx`aV69I)A$#K#`gTSxZT0*9?Bwt0tIW!+%SwVM8d9Ar^E_+ z_zPzQaR}X;Gf$4$2)u$-zOpIB%%PqNrkT4~ zusV1viofssF!f7GJDs3CO%|#v(kOmZO^i;JWl7(hbpk>Ti=RLY2|jiIrULQje_pG9 z&D@}&X>kGFd39C_p+O(J5`xrDmp+Pq>We*G`5*|LIq+`i^!?9{&yj~fn`MU=W00fh zM+aQ78m z_z7Bk(BRVQAb|9+g7-^%7mZ$P?+^p)3aPk#L&}zkdKJBX_Cg% zbPCkDk6a*sR2SMzx*@kph9;U8^XDV0cK%f8eg8!DA8Udh+Sr$g?ACQ1t+(1?u)UtT8 z$2f>8i!3(&dWV_(&$SM-N)>tp&+xCZ=cbufq9%T5d2kOxfYf66e~8y6kv_8$D+(K2 z?1~VbGbhj@b?+TY*8cxlU;g(%Fk-o0<3?a@UdgcE|JhNFL%MonJ#$$QlbNno=ZyV$ zh3H-DoCR8Qn<1ujDf2O#_$6B`+kZdt0q>5T-Ef&ML<#M7OVVxJM5b@5Irnxbj`?`O zoZKo`P4DaJHUA{gf2R!CZjp$r^Ba;~#lVcg*MG|p5g?oj1aA?L2IGk$0 zodv93V{uE5)*7}5(41gDsMsB=mMj`>Zs>_KrbaBv15mhj?2YhxXMRVzeHJ{57G$Z% z>fWVV;Z|8mpHhYuk9foK;f$%Pg4AcEMnZl68(oELXz(8&za;o$5@CDkbkKpPRwV{_ z@$B}AQ|A}QVeW|xiWU2%L7 z53IPcprBW8w!V%cTni~E85Ss~lx;fw`&i+`k}2uOp?%F4Rq&fadk&d+XY^85*Gj(ocS|3hML z=shPpW>5aUVX^V%CimMwABJ6>xv}#8-d&1*!S#V}5&!d0{lWYd@Aez{BjVoo%zpCs z-39nI7nfi6OlR+{rXs8Ftmcm)=ANUmz?RD$%zyU;IpQC4@{1IEM^;gD8klS!_~IgsLR`R^D(Ou>h{@b0>*rDbytq{L+!e-9Tw22aM9J{c-8f$L) z$^Wb9$E|$XyX{{FT{%+l_~ViE21`g!yDbKSM&>l=|mJTEH}-d%v|jVS7i1+6?|!pk2HJeUI?f*usjpU6C?;rq^9$CG z3-K&)gh1vPf%k4Y`k{c2ohGnEjgfC9wFlTMoYA2U%shW})1q_eweJr?*b*GD9byhi zD%Wx)<+z9)~_fP3qwi!)ngfe1yfrMY#1MIizS#$slGqrndp=R+qTTtnjoqd1B><(SOKp1CjRa=$d9ynlSk=9i1v>n+7@endjBojfW-N1MCe0s!AfN#4i;Xd-FZ$CvHyCrJNh50Q09n5!btWG0rLk9h`yd`2)p=bGt0lYZfoR;t$r4_! z|4TYClOPh0iGEYhb%PK@NdCztv}40QA`p}G%!y0rT2NeEb~Tn(GC;SmnPDSQ=-Sf~ z`sad?{P!0d3T?6R&DJR|RJyBxPgj(uSfbo4W8T{G!9uzHBzEORMIJa`W0jiMy1hfP zE*QcesyPpA0Z-VV2fXomf|b`_@$oIYCQ9Iwjlil91Zmu1A6@vR2}pe9!1Wz3I!SR} zi(@Zn4uw4;$72kQ>HFPS64cvif5s#4cg<{~J9B51m*-?gxyj~>dS|*yS@Ghx7;%nQ zCg%IYRDuRwG7bJfbA_kZ`3HbTbZTFG&@`h&g8lG6Bkh7~a)aAF)=#x$V~1z3VQTg#nlf z?a~3&vTUqnmfnY_72?v^he}&RZ%6v1;E1A+m?HFu6v)y`gIjY zXKYX|B~=@H1CPeFFRTeuY=zsWg&rYci8kl)g*mEJeK-a2u+M3oXCQ*AK-fHkIudP? zOvb&vW}xK7%&0NT-F&w>`iq9Uw>;F_+tk~$UA;NuIZaXGjI*=L0>|xL9o|L0DOtca zL+O){k*7|cvdrpHP&%X8z6v*9(j-_XRe|#OWtlQYPAYxoLXpyZ{53vFZhZ)x6Uw58 z)C*EbYRo+9Gs2ab-YjVtcch|;GcQJCbd-sbPhI+Cn4EtnC`pR^0&-^xfte>{K!9K< z2zHd%1egKx&b#JNi{rdK?WvyO>~19<6Q8ccFE`)rlNPns)L0I{LCBCSlGP|03~q^B zX3a6#@P9Fjx! znly(zTAPlZ<$Nv%Y8{|*q%&Gu*3)b~`8&IvOU=sWbW4EKY;?iTXJg$y~=- z{)qmKFiTCq6BgRvPQVrLKwgB{JFHwld<)W?m`8~waV**|t`L#_!1{S%lx;=VFo4|N zO=uYAqBMgZ!byI`T`W5zl52P>Sl^mK9t#z%CT2W{C|Y z%uy~tH~fVIm=KpJshFbYZ{%^9E)iYZ2dQlgu`yl(?K(rZEag69U|WWZre{BK2_Gua zAtU_azR@}t4*3`KLVxYL}^71KoDBZSIy)Q>}ys(^Sk66=x3CF@ohqQxaCRt!C{imENcc1_5 zmjM1_nl5cRLZs4&2x4Ft;~lsKA(JxhT(s=_{-(t9t`Ee5om(T@~G25{0z6S z&5Opxt}5V^4((PAkEKNmzD>mBiWtI=RAJCz+fzkQdq#71(LLz{Y9yZ3!&y^B04{O6 zW)yE`Wyqd3le^_e6hs$7;LN;JeV#|`{yyte9l2YsvS6p|k;(g2U+x5d?G68RJb&b6 zq)cPFstJd-3Hf*+V~vsABUe^DsM%3~?d|>#Pv^i`*S2=yIBA^5wj0~F-86R7?AW%G z9lNn@qp{Jj*|BZ2`S!W@p6@Trwbop7j(3b_P}uCP%D!@Qr@GDaEx;eXqL)5wxj66F zR6BWACpS_OvT6?{ge}+|V9UJkLyEd3*u(T?_{bbRg03WNZSrk(_)1%AZKrGVTX6ZkkdTme7{igL1d?UR zTqbV45w= z79_ZD!}+eiuqevpoE7RFSH4Mty;e&P z^4w@o-Pka6ZoAUn%|QFDh2}@5{DhC*MgX<_Rn*v(0=<)M&?9g-$u-8LI8h6E$+%(m zX+~m?QFhFV(akmm$L2|?weV|KHfq6)=mOw{6Q(mm>>PP&L%!-ZYQaC~0XYe+e+1fL z9#atKy9q+FWr_KXT6h{3vE5UVIH~z_TWEHLWmMIIllUUEfecJV{&y>uYZ}pugKjU{ z_?4o=X|CVpiNlB>fOcB7=k{R9SoBoc_fqSnV@pzX5EDC; zqzt5pC=!sK6*pXzNsyl_wMLx4)z{Y-qZa$7D`GmiNm;QfdUw<^c-f2kV3f6V^yi+c z&af7LbBOZtQ<&6b4EuWV9?|DkIjLh!a3iwStVCoA38mX*-L7Yw7Xj@z8R@gda@`t< zV?H8m)daG`}$??=a#&g{K&8GI6a)q|#1kLLgKo8%4j zE-?OJBMNR|^l^44{Cn4DJ9_iMYv*;e}j-sg7Rpll; zA)^{M%_i;ZV4BCa5cj0B@g%ifYinV)aOeXp zayiQc_^K_GpTK!vlo^+nU24&91Vl!@2=`9w__P-UHX9Z)s{sOCxtZMzr&`)6T`eZR zA<)g(yM3-L9T?`nc0)77w>kD3a;ealEe9e}G4`_2aHZ*JpV^RC=@sd9+u`{gX2Ssu zXEq&EC$vhXj*@S9en*OpAP6`FO#LVzXiP$2k6E1T=uDbvxS#_HoJb){kmLx|7bv=O zadLVry1{lpf)J8d;E^pU$hFx=ZGdI-8sNDv%}d~pqRuj(H!<_>Oe;bNkgz?_EuF)u z56Cx8Ww`>CqOA8(3@&;L1uBy4X6QzA#6^yR1BQ@zhGe&1>6Bx)UQv4=8M3Nd$Bs92 zpp^t9MI9M(zn_upq;%Hx$?1k|sX~MFnS%bpLN@prrSvrRK{Fd1T|jH&3{bRoPJm5?z37uUMLN|T(MTdh)*~1T=j!I(Wk^jkhVE*b)lc5woL|5)iuFN^Xz5qn7s&$kXw6pX)ApiSMD&j@V* z1r0pSH}_D4lQa3>W0ULL#-VN-IVm#dPMAxds04)-_#We{F`XCTKF`1+B7i5fj0y$- z{mqK_b!BydV{_}q$ID~Q$OFczwH=%KuV^V*)~izsQzyu9(G=d&JYv6VP|usw!D8tU zkV*c?hlSZ=#>*g1d=F3Hc`a8fh{+BFIZNWP&K>$zV&mFmnW&i}zu3>`4QCq~1jMeg zcxxB1!~(Zfidy3sM@Oxx(p8U$)8FQmyPp0isHjkCI+S*kZ%yDaOcZFu8luuX3Q07h z#|z_-`Q_6>13Z;v7g8LUv)OT+aNgiv)58NbC+E8`Z{s|qdru|s;i|cq6RU4A?Tm=A zcOe`9{Zfa|zhuHA^J&QBV9KHMDGH=FxHax_n9vi^Rn9Qd?d41|`SU=3nx+Uhse?Z( zs5SegKB0Zev>=^t9?Ox)@@zo0YwBtX+vj?DTfwo!!>-1qUZ1b2!DkHvQh-fs-J?00 zX=f1_ZuUQk&4CMs1Z30;hN?_Vzp_Pi_0z$Ra?kaGpI_99k-i@6GD?at-HU_g@OZ9} z2We0HBlp_~d`ogq&h32<|MC}%FV~hvXU~N~U`~*MbxX{Y^z%Ht8%2~mWz>VXK4~_} zFq-P7!DLcaSprCHApV~8Lx)Cp;OvW*$nf+BqpBw~vnx$iwzwpYsF0G9O+_>=ccbVU zbCkE#o^sT2P+s8AgTDat*uC_R>B=1#tOHfwY~r~0HUCuHOX$5%e-9w4dqxliKW*WY z_=`b!8+O4W2-vd9faDzpDFBxeqVZuV^u|eLYvWe)*+guc!Wm1k!AeR8024M3qqlJo zS2tzuO)(eCcQZ7tT1u8w3dF6(Z%df9Q{WvT3wFS4LcW~0hm3%@@bA5FqB6)>}9 zbDXdf*$h)W#RvK#)k>d}=NtlmC|lFo%7a;|e%cl6TV6^S4>!$HLuKO5WsDyX#|#*4Rtx5|6dD0_r*yM*h)qOimulq zm1T5Eub~ki4B2#Y6^X&-+`7Sw}s1A0Y+!^Ca?Oghw%a{q-yna8_!l!lGGg zV+ij#M(Io7oIW(j>kO_V7u{4(IP}0cHTA7UJ-AlS5ic^zdnK#mU9xM%m(#Yi8fVGx zir8;zT1xV8PtxEjrA0H6yKT3w?P7oXFWs~fKk)dDUOUTwCY%fZ!PwCH`&Y^lOE3MO z^%PG+Wv@``vm*fuOua4w-&DKzq|s0Oc{VG^DO?pVr3JDT2nFL$N~%MT(qOD>?h`$-mBvmdCyRKyRYO%f&6Ybr zlSTK<*PNSrp5{9j4J=vYYf#7X*=5jGY&*~PT+ELt9GH$^%@dUT4d32%2jdwOiq)Na zqvzzT6TS)a@ZjH;9#4~D{GiGaAn(x7C?9T@i^;tae({$4D?{=Z9?9f>Mdb?+!U@I}mem}6o`iWu52#|y^R+R0NuaOJwQOz%cv>*H~B!b9EL zg(+W8HbCRFdcL=1wyNPQr^S2KvZ#wL$QOVhlKl8d+@5lQpTGYuA~`r zH+HSjJ9G}}*m^g&w^uhdI+FmuCl4)w(bDD$c z1EwC@85eT0fKd&Z+>$Tt-H1nxa2=LB3fdz)yADMT(I zZZ+JM!4Ho4q6*Y{fK~Q@YDNCGBG}{7Y_{@WCP08`w5WZ+s5Fh)j47NB^-Lj6+PeeZ zY7g=5cBMKB3}Jo;C=%QYue-Uhio~d(6AOSx0|&`6iAknO{&AoD;}#H4M{WLc&Ntvv z-IFdSqA=(2ZCjb67RVP1hm&Y|OmO0RcLd^SL5=@pAc(}aq*0TnE5g-mEGXY$06Q@t zAt93lwy-aqP%V(AVQthz?m~xy0nzX8K2LjNe}G_0x;%M>7n{>x`m&X(Je}v59Z~Fq z9fT%!^O@Uw21gVP;HVGa`hyy*UH#7q7|`p3&g+mD@zRKS#SVkvTtT$8zq^+r@5)&f zj{O_D=@AS|LLmDUC;ONFSs{WbPAXU28cyL3B0wNPemz35r*m-B-GqO>&(g>{(smOF zsV9G}Uap5O(}_Ohi~fPX48TiZ(cqr%qg0$8Wxvh>??9K>xp%!4@-KhjdZ? zIpQzIG;!n$N-=1tsO&Ra*Ma8{xtRZ?7XigN3`I!cyQbH;%)^^r;g_OU;S@LUdHQsJ zQ`1N+k!*t$Q=Th7(;vNw!JI&X`UE#5dPI~v^)%+^58kAxZO@7p#@?2?>Xf5gwPS4k zrJb?q7FnP`sF$lFBO|9rni-31Y=ysJe`1-_ERL}m{t&F(h|w9alAyiZB+>GR7Q(A` zsnEQBib-~_St?u}vJyqhh2&;5ufNYgp;@RbFbJqVSwktl*R@=L%Ht@G;^&F>;8$PM zmcHD(=R&qBl!G4_BVH_sK|@By@_=ki_^=|=Q-~l5cMDzqLTkpKD2iR)iz)m53SRex-A6}!^e`<4p7_pjXUaQ zZ^Q_B!o=;g4mpZaF3VG;P;BXhE=wAp*kqq~Tc}5t1zAP=Cmuxu4vAu|zCyxVyZP3#qX0tf<+HOi^l*7a&9kKBcm2YHyok!7-!_p2mwE*kuXjj1Ex zpBQrBKe5+jm0U~D2A!rekhyDjc2=aqK4N@RMCG{owADoilFpir&YS4+|L#D>eh7OB z!O{ncAhh0|7qi&t3~5z7Td9QDhpeO_>5uc2D0s3PHUwc5+FY;~+0az)a*t8)K{isV zr+?S&ELxO)fH%sABOB-5`4`bcPAk*+ql6otUscVM{vu}>2(PiLZhAma(m>#(gTsoM zEZ2&b+;14EhbjJ->MW@zFh{P!xUk_*5AV-%A{ZEyFaE6+Tf%A}14)z4PKSI`elMv- zemVf$fVP`D}FJ?$}hdLKO+&y&H zn5R)tFco$9aWiLRnKQO0v12=AJs|U#QNX1{l3QT_yO1Ujz-$2hmDr2v`BsoQnc4*y zfQr;K%{^a=lf*^Qqaj~QY>kPTHC3-+{Id~CsIS2X?*s@6>Jj9oH7#vKWp37DPAvva zfUDZH(8OFtZg;Ku^Q)@4PMy^PyaLzG#&+I)a$cPqC?zWZFmHD*8#bIY$|K(+7mtw- zL=kbla~*Lj*sW$B>UckHG8z5eZXA~X7ZD5OBmX_e9{F;-t6D!?$ft!0(LYS3J&{_H zk77<}+kjESj6mp2!2{WrGGfnCzlF*#e-UJ=6PfRx@1p2-(>2rx>tI{|+b*Zox_7Cq zG3+-0MbNN^qHIC6m>Mv6%CdE5QRIsE&wRg_<@HK3ubuMu`g*o#rC%l->Zma>>0om;c22g^IMK{)pc=2w!6ZmR!ffP> z*j_}}1GU~;Y@vIf<*1!6>eK8v5oGGGA5H>Y8|E`&*KI;eZzy2t@YGUociSsd8eY_T z3JJp+au05$E)S7!UM2Q{Kb#(ZV@C%`w563% zL-Px-Z3r9Gxq019hnaFWoa#-kOkH&s^MsthT0V}wb0BcioS~V-#q^3GD|=2%-?INU z^OMngh<2k-^E~7%@ql}Aw|)Knx0=s?97BZ8qmSW6d|=B222b>|m`u61E3)R=i+Ev2 z*{B5$mGjHTax&5_I5IHQbAYG-6HnGv+wKe-gAzduiM=mmJ~+G7VXx1MmI4YY&~?gn zRvt_hp#ebZbM3?04AMUxyhKJI1YV4dozF;ACB@oHcwc~PJIrW0|Mll!hxCdodOkU7 zpJaQ=p3pH~kq%6#;GwceYPMNwQ5w%HS0i_$jz-IFL(rUPCz+v+*|ndzK%P^K&+6zo zU~m)s$PNW1(pP8npXOLGp5lgTn&kEPtr5{T8l;UrKU!Ap-O4DuM#`dyk3&G_qgqE) zS;@R`W4HgI?4UG|wa-ZZo?dP?Hc>+g0w6x5t{y|MS_Se=PR(X#h!qOX#EMxUoB;Xh ziS9BB%+w9l$ihLby1z=;IwL|yj^KAt3Ja6iOo93~+FC%h6)I2Z&tfQ&JdqMS0ot!Y zD)#o5;W<1$2#W+_IX3ZIfo%yN%Xm7zrr zk#XrgD<;3xxVS^aqchbtY&Zw7JWiWY7u6?x*zU;GGqdd|%TTa<@4 zJ#PG)zm1cY{XEGh4p{s{y1~=7JTQHBB^45?pWzj37o2t2L8khE+cFG66d2-_KVN>@ z`T%p^Z7A{pygzbEWyo$2C#It#-XZ>m`%*rMe5Cv0=X~O{hpE`ntgbjU4Ikxaip4TU zIm=iP1n33Yeu*jH(F#0^)AuoVaPT?ng|u1L=x6`EkI%?$GxU%~J{CW?gFcGXJI$l4 z5#!objjXG?Gs74$yJcKEjlg|9iHbAq-6h%DX6+5wj!_~~l`Jrx@onV@}?TiI_v(+G#mDm9vQMYR9Y?NDU% z&L%94ok(B)w&PD?s_OB0$o#-=;YN*!92HGw2F_-fx+a@APeq@FF!^O=%;*#ZL>omy zDc|tc1Y-FbG}C4-*6q@ux)h1}Yf6W0*sJz~q5HYgarx7(@hpOh_A|#`-E< zk5t0TT~;8TcfGr{b~t|2Il4wA_HUQ@ zJkX~4ak@OsVj*TO5p|eVxTtl8O||+%CnFKF^oGLH+%b6iDOE=O%DCA)QF>1fXG4R7 zM04F0Rj{O0?iWP22TW)mIGRqXTqAIeXPFf9s#S&S4~QzQgXOV9bOmO+<4?)$+S@IS zjBc1S>4m|4F`8s{R-?4XlDyODl$xeAGEjwh$KUvETcStZK27zrNfb9V%O}oI-hNJJbH{GGYdFEfPDDo9ff6;ghs6wldzEn zz+a6}8S?=t5V2=4My*_)s-Ak%Qkg$x;NvgkOXt_+Sl5fP7e#OHbLj6jVgw|+zsPv& z7F`~6uXBb28V*;~?wOHdoptmSrl!P38GxS^(f$(>b(Y*x<4!oM6q&uF=Y0!`t;F@% z@7!zLgW^*a-Fio$^RG)_))w9foKg<#2`kybXmSV9QK`Uxqk}qYTBwt#$0!))a*iKR zj*6*+^jq*05(FoD{?WV-9SlOHFx;Bfls->f93yypuVlR@?#bR8n*Lh4=az`J??gOT z%MI%DV@dNq-+xN(0i(8fB>`?qesI)f3{_pVR&OM(*OvUj8w01zWVVHO1m)|vS>(%- zy3Ko_QC7}1!_qaKv2cWV;;i!yg5lNCY138@m$ys8KP%saF8R(Xx{L-6*DO8mR1fqm zN$OE3tw10W9M?p|km%O^eeyg~ir!CI@be>Q%j&Uk=s}Glk!*;DeF@|(_LXDhT%qi#qtu`S{N#5G zYSo@gm9LIE{e0XZ^xffQTHVN9&iY7G^ZMJ?0cX#IaH1X z)ePJvy5Ix(k}q8cIk?0q+}0pRD?&DiMuEs`*~Hc~c#M|=eim~QsndS*fgskv7Ul;k zI|I2q{KR@``H{WE-p4rVoQO)|aqkN;g0RGM%W_lqkD+yJ#VGn(-s5c}v+(PYrjN_z zuOf0ZeNW$pkyMJtve%y5BK+8Q*AD(6_q$Zou?%qhNt3rR{2k<_^@lvlt-=fy8jfQQ zrWQX!3U1lj%D{uIhM(sm&;CawTUv8ILB@gdPCHmrvtW^V7X>J%V7Vmo|B_;yRC~w~ zdh^vXHLTe$dvpV%^{w~+4t=-E%KQ;O25^dEYOSe`mxDA zdjH05V<1<1^bqnfORkRJ6E8lF_nJo`cG7Tz^|BhDTByeB3Iv=a|g?hhf{t_R+;acz?pbrchQWZiRjDpgT+!bzs|5 z^Z}YztYwzy_J=c%swe~zXsHlg&tAq*QorfmeLA`4h!QXj6Mz#M&_*|fDhnOTSvPB* zjdU?Bn}iOO6d*P?x9MH&9#^pHD*3DeX8gAJ4cLWwLz;XDiQ%kG>~s?M>I-beeCwl% zfKA7WGr7EKh!URJgdYuV8n^uH5vIc^69e^v_j}aIs&;;@7`0W&qUaEeC;Mlftpzc2 zyLq1nwrQS}sTz}XC@D9^@~?Cc>g^J&=zlW{uu{3{5jfB&-&XW~#qv)pL(dk$wRuYw z-7tUVoeJh&9jM#B&?*nJUO|qYQhpnro_;B@_)CyDSFZl$iB2Ya^K(ioEU)`N1|!wL zZxJpPri~uf-R13`O!jpPP0p@TTBp6BN@1q1qJPc@Qejh^0zrj4_W=#WVk1i|f_r2v zc;qUH=lDZg73S}q46vDzk8UYP!!C|W#Aebhsj#X5OQuF}Jc|&oGIwSZ@@PJHMGAYq- zmBwhod~0>LU;%cNhbMCdZ=N23 z7UracQ1Ag2CNaGXmnkM2t}Q_*M_7c4uEUxZsFbQpbbmN1oTTT6G6;^az;!2ABv7an z_$)-E*h1Kmb+@Ov<}&wukeA=JPKg@udT>9+iTjGVw32~Hg6Q-lch>rk;NFhiHsQo& zVGDnx6ni*Uy^#U_ZW%4d^lK5$;J%(@3!_Q(dw3~UMF0(*a|u2w@Q?$Yvs{NCdQNC} z_x=EVYkR*?94q_w1eIL`ZI0XR#!9KPDHZX2Rg}n%PSYfKir>lF7X8ru>W7)LvZK2+ z!_^tzIG-Hty2;_Xo|c+R#Ii-c)6c`Izv&as<8vL@QF<67DF21W31#~eLp1}Pk>=Bz zgDc~m_kvNqeyf-<^Qua1O?J38kD7N37KUeolu5eQBKI$}#%{lpFzhP7tCGi>FN9-}e8B{A%;#&+XHAl1$$0M8F#n zgoF)|aZ3Vqh%FdGGc=wZE9n^xY{5l8R)|0x0rw(*5?m3{fH#v0PHb|-2zLgV)P*Ho zSJ@JW4p+F@pP2it=+g39rv!DSL_m0FR1nN^#t!DnvVQ6=UyrNvvNs}2NkPZxzx4fE|t zqPAB~8rQK{fN&cJw?pR0dtaw4brm%(nn&jvIRCKqqr(5mVpw7xs)WMwx0Nqe$K5e? z{4Ehzwnb$IRYc=A1qu%)Mbex8C*UnETe}0vjekwgbwPzwHa-U*LPDTcB)7A zz1|y}1xF*}|MNgvg^`F1dW+ob@6p(FJYIdjEW;julj(z6yvneZC{hXy;pR`F*| zS#HMh6q2PbXNN{@v-Uza@@uBgeY;U=dZ%%}u9N{ISzyVHEylrr6gmP3>#iV$5o3$q zov-@(W@e5-DW1**Jrkt04T8eZPq@BnaA+|xip!JDl?JCZZmdNAsvIHcqjioDkC=3R zvXStkW_#^1U)a9oVTT8hjWk>#o-wNK7{WwB(^Yo{*TKSQ(?T(h{s1TInVF7x7LT2~ zW^y6-Tp@P%KxL^I+>txlp=WN1E9IhDQ+9b87A2?xVl>XOd^Lo8jRni<1@5U zj^eJNws)rx$nVf1&+^FT<6iN!;PS*#=SRL`xZO%I#me?f#)e~2mBV&2yhar8tX0j4 z&AGjbF-P5}iLk>OItY5o!oFZWaptJaj1C@OVKB?XjPZYv@l!A`%G2CT9P!`!9rQphro-R7?>H2KXc*je*X&mx zR+kFKdmS~5GrqqnmH`)2)zs>o)M^EiWBEKog;dJl&Do`CSc7^aAZN%hdFu!1a$u4m z8e#CrP=h9U5d`rm&CJj z+NHRMiaSr-8{K>2++ROlKA0Y}-8Ww^H{4%+IU0ItsM%^I+CAS z)f}dt*2W;0djuZg;U-#A`={liG#6!4nF<5z_d_9?Eiod?c?rvXWB1gpta4fMFbZnL zuJ~UCu^ox2cDdCKtux7FIWA~0&fMZ3onxNRL$AttQ@qN$ODt!xdi5THls0k#27r&+hbMy_2z;bu)XQ zdp*)xGvn&&eXlh^x4ABx!8?p@GX5%}LZGZ5L@NiU4IW|xe%v#}BUQt=%THaR>aRE( zmoz2xW-~@8i|3(Otpzk z2`TERd-;#MYYFy?zzxPeD0JJIRiv?bs>@e7=eDAP@V6MH++RD;Ksx_wXy5 z#~+4z%jZ=rgHyc{TO7A6tE`!qX-nG)?f#qO(!)Ub1J-x%hEmr(i{`7*McO_N|J4HCh2f7c z**LP0VO6l997$obuy}g6VFZB`%H5$qmL<`*zv3Y9Mwm+s8?FhRBy)09(Q%SlT@;A7r;>WBY2afR!lJSL)>e)vl2>3)O+@fcqivN6eq!Wr^FDQYb@$HC`!mh75bVKZg3HmMTUi zs&?TQ#%AUNt~C(Xzp-V{@lvz$9b=~`WYBGDYH^wVQjlv!Mg@}R+J{O|#-b6Ur{_;2 zvlbs({6!b>l$J!Dh5Mcx?VAg6IzE`|<&t7yfKK4nCA;sXQVex)mqG_QoOjT@r$@Wy zoi*E&c7D&eI$|2jq$oAV93@=B!IH9bUpoJ{nJwF?a5c{(69diIg)=gIx+xkPnF~_kGt1y7gep21s7A;@i(m*VmSUFHs%rfH;r`IA@&>>+ z%X++wt)kYfP=l?(JFVVsL?xr%!_$syP{*eYG!sbl2&pb{z~bDf4ug1LvXho>z_=#AR=?g|C;4w$hl=8b_?QG6{MHsX_lcDU$H5XKFG5f}-y0H*FP(YecqG!*&{?y2=Z1?y}8?Zl+u!a^3;MTUbu{tU#{6fl@lbDXm&WQ>qm{q zNd>ukrV{MXLmAby`ijEQLpr4p*1##>ej56n!}AAq%0M8i;{$bB;1(^#);qySRys|{ zDu!`ZVQ?#R;zr3^4;LxSsHc`SWV{6bL3&^1GYZchwhpLgVA8ARk~}|8vLL;=v;sx* z3r`5OG#S=EU7S^JFhQl`KkT=UPifOvIQB>APSDgGYE686Ahy4%!u*s?z${dw#L-j^ z+&6PT4MV0q)YCMNmXy-isv|&C2HLXQe0VJl+pM~nGkB48Rdm*OmeGI*w0YPe&mx#BFAumZoqOfP*Z(RRdd+VN5MY zexGc$MMKw$6kCA9QP8kG{gka@$D_q4lD%*i!ttb}%RSEIJo$^kj6>M3P+o$$av_TV za!q0GMniaVFI5ftfdZ$fSH`d@r86V!UoyHM+*`lcNC)?0DFgm4S98M{g=@1yc!rrL4=Rgn#k}&ff+oA_#F!gX ztf5v4MeV|&=8_^aOZkztvO`=wiT>G87sjn`3h@?Hd18O$q631YY)hs!mHX1MzRJw9 zm6uly#I>j6UnK(V$+EdIj}n+Pj=K!CnZHtdYB*PFEsNplmhg^KqIKxb?(X1K~ZotP@REbdG|dD z_OOMZwl`?27jTIh8ygD?sxwKK{zK9-giSyI!2UJI%REUh)gYt@P$ZXpW3uYj*(OdGG2c7o|f2meB zkm;*FA9*;J8=h77nAjVJ;qP%C;T&^IP~M@@Ufba@r~Oy%Jd z&P$?G+)#>_4dsrVODxIGe!C&?0*jdPqa#jwQ3Ji466ZkPUOI&;DwMtu9`czr0G{lt zf{zm4{>(EHr)rV3wDb~EUF_KfjuewK&wf@ZyO=}aU-d#|(m3@e(a$#|aiW|OL)^MLjapM9l)y`~SeDOt7iz zu(w>FAnO`wS%AtJ3;q^VG$H&hgt$#7?*rIZW&#?3nHF}Rcb{jK zI}`!*zS?+I^SU=$Y3FB;C31WAZLBz|1oG&@9nwb%F7z>0J(&)nwfBh~bFwnE+PIlv z=nw~Jm5my)=cX+mq&-b;$jR-c?~?fuP>}NAD>S$#4H*5M%#V^(*4CF*XNhi%$8LN} z`YnD_r|LQ5-krE-<%m-ujFeJ){WDpc15Lr8HI%`h`56%_SNOBp4;5_3(sY#SqZfi1 z{jreh7Az0q{&8{9F=kv>)_yq?j$}Zut0dgx*f7L)AyB&ETmk#N(H=FtPK6YB%A{L<$fKzw1u^oPOCAdq~BZ z<&-Uuj8F;MYbV;F=^NYm`i`4u#7Oyxi3;sDr&Jm|}UFK%yiKo??O zig^+sNBpZ8f&&SZGJguAK$%R{X83%eY(8Y+X;N3Oj;dCgNM*q_j8&MB=8ab#YjNr4 zc_4-&*wr2RJ|mOx!OI0A?!pxp-O9nJ>y{d>a|?))M>^!UTG&RhTtSu$alt1pwQq!Q_30toNLe!8$h=3SG9FqmO-u9X&C(b@ zOX|)ThGpyBf1J=<|{}^oL`9>jn2-Og3 zJ#}&((W=2<0I8+&I3cOwy8#1mEfwcVj!-*>;k7>o?H3NOIyZA2ixZB;ze2#Me-$9{ zJl^`j{^_6xh!}q5Iry+D|B_ecvmo`d{Li)K_2FD^zzT_2em_fR^0md*yLYrk_xopy zkXiAvnBK(U2)=gGa8K+!4_&N7m>X2=W1R6U`hCvfeirQTW3I0(%8zP%zQ`2^+2UES zRFEQ;A)Hc6$O*47;No}Fo`=P($Lp?a&aA%{8!)d!owRdm0JxMQpN4c#1TL;5)7Ku+ z6-aBd)%(N?3!gYhMTFnAQI@f@>U22pm{of=#HtHjF&<*6Ocr73!Vs2kb%LIJucE?L z%H6dRU<2^~KXSr;Da_ml^I=x3wr4_!%*f*HJ z8dmMQ&Z(mGk*IytC3)B+3b7|z674WC!pQGlWKJ~;4QVc}R%{@H(nj;~wGv0~;ed;; z^o%OePwNN17KUFH{dHt1_S~rvdHyvC9X&)M`!+#W*UhJw!>{Ci@ zK}gH++-!)$kI4C!ATDDRUy&Cw7}{_4WVhmU9L0Z_l3$4$ZF+cpHb9+)C15ecJ<38q zM}Pf>D(a~BMcIzUYRTJhEyst=UrVB12HTr!X==&p>r=rodkbH6ZB5U3>WSJSPP*ED z2L`mW;AE#oL|C&j10XG9B!v!$8K+~TRonN>I9QaNdOTHTDve<{E$mRmx$8{0MHpC? zLSSWNWo5PVc5sza2IAlop`ZM%G4SYC&A*^+)^!l}WlH6OJk25$0wr1M_C=lLoWv_^ zGMgGDfgu#@bHh^=W1;h2WwBs!=EV1 zYmQ#nFOB8hPqe)4G_l$^F%I2MCg3~}a$~26;2}tOIK@Ey4vxl$5%pu96*aehjJ6v*pXSc&Tf{$v;eChOpL9>!RfKxHPnnh5tQw)B5M_=l z8CrJkkAk_-gc_U=11ok0RZ1j9XdFanKl`#eT`#$wBDOe1J5-^gD9&MaYP_pjY{mqx-cdIe!Re3qry^=ZCCko9Im^u9e8M* z8Y$I=UylqtY|zpqc_28~t^G0VvVm%XO|b=j54|s)3%s-yc9{Waj9DX~bODW&Ddj|y zx9W|FBnH1&}6XJn|6ZJ-Dx zltG!9iP*tJf0jHew5n*28uPyWT;@}Bra;}YLoMvJ6!{l%P>42YGh{2RjEp!$@__~A zR^4#a+>^Y{_4`q#uTb#0UDB(DX2ndxciwP(6VG6Z zz3-Z{1P@6gQtYow!}af#qw8$ASIRIklylrQZbl|%D2bENl#$!pZZ%kDL}uUezbAj~ zFdqmrApj`C*~Re;)N)v%+pqJx#6}qcJvbq~LOHo5?xI>@+2Inn4`#nz`Bj+)5n_}K zb3nGRo!c$ZgDjhP=2*6^3&nFn)ODG0c$mpa^N*xNjVYp}O=Ahjct>{l>1(;;ILzq$ zQ$GbwQSctgep6I=HEap|wEf@69ay>u>a{wh0WUT_i@xYjKkVtnYYQXzK5NlT$aEb^ z)#Xov6z~?F+$IM<%&q6VP@^ydD#N3dO*Ga5n3}tv-jjBVYkAq65EP;_#lSb=b=Xl2h@4`RTU9n7>iKH(F37jJS>?RCdcD*A^C^IC|qO#tYh+=J>X#=g>Mtj67DHvr~L!_Uau6ZF2jvQ7PCCS(?IV^;5nx zPq7Dd3576H4vKW1A)nuSv4Yk1-|#sWa}A)Itc;O%MMA%#8h_%(CI;?an|>*Yw-`g8 z;a`1hu!5x}$HSVn#BM5@8-gUzpz++yxlX3@Akae0Of&JAa-!~*sVPm(A(>ZN zYDJ-3+8O#DyC6xf*fFxg4|T)3@0u&ybspAQ5i8N}kPmI0K-^qf z7EVH;s-^|ZQZ->zw1>iA_Q75`ej|_U3gQ8z=wGgY&1*wHwCRr@Ay0<|SiX?fSIN6fGk$fHlr_MbomX~DytzUxTV~dNMAt^b_65C8Z$GEXJ zG`bZ_P20Ej)We_b04yu!po!n*m8j3x;H4?~#-Wv`D=9;CQ(Pdzq^aGU1mLqJ9smsK zbjXiN*ox)0Y8BfG7DcRIR>4%>UkB(Z9vF+LrW~UPVbm&-LDw5_qtt5tpPqeIO9CM~ z!>LAydOlm&0^W49tIrQ5!oHwQOx!eeRmU`(IiGQ5Y=WK2%x;f(l! ziH8+Ym$xK`nhYSnDEuSj>d23mf;YG-y-sVQZYtweB<>L zfwqFf>Iy=jjR($bJBxG#Z3_A|@1;=GaW*ni4;re%G=R<|!Rjw_S!dA!EQE3aRtaGF zq?(3q?ZIk!+9U4Ml^XXod0A?gyd-h$dcN#iKHfDsPXb>Pd0{I?-2*!IzC^@bJgNb7-7_TDTQRIB9T;_%-qj+L0|WXhix1FH z1F74N`}sz9{Xs9}TFI8?_!dbnuC-=+SkS=&B~k=FrDB3i|G-L%4p}t=bCyc}#4AeE zER~|KRZ}Lx3a38Wpn;lfs#(nWM53TbAKo=UWAUJ1{$e;V5aYI>qcJ_hZ{~qf4NkEs^EiD+_|r z*8;mV_hlBF`OD2tn^*XQBoaS|)xY5VX%!8yX%|*i43Soyr0Gl z`pdy*N#5-No~?bt2nyxpsMuv*BEe9EX?X;xLoeSd5uBk3C~Ml8rIvk~l^Ay0wu|}# zUYNdrI&NfHct9^5n5r(2_; zL`4jIRK0?mEGe_zh^30{$@&9#o-SKcWZCesu z2q9MQQC2U}tsW(M7oroQw;%|jmyOiKp$6NxSDNK?MYG_F!BQS`q&jCfeSOb)|1j%3Aro_>QIo zW(Fy%x*VrOAIqCF+j!@$V9y0K9pA8FdC}=stq#KF@h>7R&mmyvWgCnS23Odw90Sed z`*^tITJq7wXBj`HEoPar0)XnGkVAcaY47#hR*~5Ed4;iDH3Lco9WWK6y*Mbcxs= zyNOmU5U-U*@mD^7_+fjH=!lsG3vY9+q~H!nCs5H1S$4xe^ZVro0IEII&MA}A<>^e3K1iL@fuQ8ODM){l^np4xzbBT?PjCb5skzN*lG3flwUYi`*o$Xs`!+> zFhLQQhP}bTfFHCN@;OmmM4dxjx{)SMf8Bd-hAjrLM&Mg)R!obsLHt%*je$GkGOmw- z0|w}$fKYQ*t38|nPxw+)MKIb;oHr6kGnbb4pTE%$qC zMVQG6p9QE2WIDy zhS69<)KNQ4I?3MAdIjC@e!$u6^6Kn(Noc0FMyWoATl@k_*i7kSkd^!?op*QiQu4`s zljPNU@Ge-m^imB=Q z;672`6)+1S8g+81-10g0Nq5I5n@szNE)F7FXXkMgxFeNx3S*jbPDD+@YH5#4VzqEVO0sX!xPmV5I$}XaUw*O!JG2=?j6H<*#kF6VBmSvj_rRI~~Q! zlnoe^pTbMPXvTXz2m(0~9X2a=E6D+fTPyHp*2)>)8R?oM8D{NGf(1N?A>~vsSk@mX znzTR`$L)oGnp@$EgD0`kRu|P^%fw1_CD|m@`dy+y7SZ3uTv3a|6ZaQQOnZ90=TeRs zvy{?wxcBc>pN3>0MO^hKpN_B5yZ z#(guI%fu8jB$0FZSW%jq#l&-BhS&I8*XK3R$GQ;sQ7#p?e-GA%!E@|B9n1ml#!D}C z#a+%xi_SEmgmvL1q^erUp(zKZ;e7v%J{>%Ij-}e!#JsgcJXf!$Rd@%p=FO`mca()~ zM`-X242UnO8OnU{msYb#0blTkG3CF!cLkAOBG5H zH<-Dc9urCAIy22g<5f~OhI!-!j~Pu;KAGzlO}>?rZ%~^kQq1Jt8S^e4ygX(ZvuPmK zY+I;}$i%RXhhv6{4e*ci9jx+j*I+L{d%YM2N27F((bquFX7E zM?guof;e=5j_=1Q-C9qSs`ie#3OJOoM)<8oOql^MrTbt;dEU5nRDqY#5SAw+Pf+Gg z%fh^no{Mhveo=gXlQuSR2&XWpmrl^FLj*0kG<#4GjweV+PxYrGl?l@pEsJxAZGrZG z+o-ajmZf8jg^-HWX90=xYvKDsM2y}=gmDO-r2FuUr;|U#O-RqVf!p%K{ZAr8*%)lL zd3HWY0t8fC-a|p<__#CEai<9~T@+#>2|#6cuGGvl-97r#3aLP4*B)_vi}PM5UQK%!lEb)?u~Iqv`2}Orw1#!c#TiyJj4XGacT-;p#&YVz?5BHgB{4M7~z8 z0xxVU#DMae9msqAV9nTR^|qiVQQCV_J}`dv09 zcf=>83NED;pZF8_S~-*y_{Bjxf-{sIa~$*O@1tbR)ZD&89JY2rLE_TAMw|QJH0_pi3gaou5Km=?YKg_Y$zITrsDXq73MCg?8MzT` z&~kQ9usW|{A*k&J1s^bM5{YX?d`k#@&e6ie0)F&}G1d1&#+}tIb4OaL@*5>Vl7Yb` zc#&5gkNn)l%P*ZzUV6tWKNuC(cd~9wlB6RY-;6yDJ8#H=;{v$wG*06R7!+lrX4tH? zhZD^t+jX-JlJqe-`j@@$^S%4D6~~1g85Y$CI+q zLZ%9M5=sQ^ED1DED$|L!w<8mgzPIq*GPb6$=p(`Tg!?jG($(U%t&a-Ew)9K+6*=>% z#g@dp5IIfd98CM@{*RG6^%ZU%bMx}Yq&^KNF)xKR?B?yREwd`sR*HtOeh6E*+Ndm6 zn5mj8ch(b3!+MME2t8a69Ec~d3GJFMDM?2M=O+UFd=Z0a)@8b#Y4MY*npJR>Th$eX zs%|yz1?snE!)mzE-oHF_dorfV5(7B=;z3Zl)@LkmVt<`BTaQT_aB-nkh#?(Kr>W#d z*89j74vo!HKsS>e(8V|b6zZb8`o=Z>;>xheetTI^xOh^!l9g7uP0!{rpK~F+9$f$j z>~3e6*)p!qD-qqm=VbhIlI~ixHqIT_BW2_0r6kb&ug@nBpF}!W8?@eME#)c2#kgRT8TeF&2HQwXWn4&mw z<*Bk?=1;^d9>#y=kTC#bFWBS_!i<8h(39((zizN^p4%VLa=Ss#pD^)5)7|FBZZ0*= z8zbFCEW^p!RU$3Kd1YgY?X5sC)@YXWqe~HT1oOCQG4qutY=ww+OM!JW8>dPYq7eGd zu0dlrQ}yMPbo4;p*~gBywhthDv=9u|?KAmPbIeFkMAKOthiMj1Gtm(Z6wYlOw;tQy zD3FpezjGGeH03ZMKWaCq94As3QIP55Rqyzk9TqDHJ=BDS&s*`GwJNcTJb1tDMod0S zll)VRq>Q$nCSV*(&?b}j$EnIK5kl?M+H!p*D!M>VqT&I08r$8B|E_DKaEG*^|46jW zz?b)Vot^$YYsBP72)R4g6eQnBz}u+Y^syM(;0N{?I(1L<7eTxReOsgCeMU`>Kl^}h zhAi=}?FxH_N!dzTTA;jJxJPe1TxTpC-#Ln%yFkX9xJQI5ZX(UuNs@>+7Q&41$t?Tk zteTZx{78G%t`%QZ{M4{oX&c*?nU?t#K;RT$%E&43CFc`?_ZURfHk6lSH7ceMDoV;{{zN>lUkK`TJg>xP(Si6X z`yw>%HBxGo{np^_7E3i%&B8)Dtp&=Kbcz{)Z#TSI7&Ewbv3BbvIKuvM1M%qW!}Kt+-_9GRKKD)x!N&id?Q{NpO)Sx1Ps z@Y%(aRnL;73S{#vQ=n6N75qMAHe%m}rF-=X4n#;SlJ;uq4^^dsBa%xguABA(Q)-`E zHFK*%w(D5U`ooN!{vwp`+#3|?xgM!Pp1T@)nw8v8A~mvOSZTddpaO7Rfp3Vd4lX0f z&q-x0>59wU>S)=vHXT!7%vVCrf^v`@OUg}5hvz#SzsTDiqzFSS#P0P+2 z1bcD9`Pq))==I;|FKD}J?eqf2`P`}kNWQ2>q_e%hY~Xl(M=bNA)RrA%DRkXEzb;!l zn8Ta_VFC8BE{d1W`he$ptDYt77tI}38wWuTe0xX0g2jDy&pRcemLcl1Mv@Skg;pOS z7eowDiw`6^RfPO}cny+ogRn#mo4TDI16-=YeaQN*2ncCqc|FUw!Jk%qZujFubGn%- z6eIrfBle7Hzfj@0oyal?Yr!e=5lh%l`2|QZKS*47pd`mvL8K zhSZLJdy>tQJ~T9#RuA zI4Jc<`7WYr%ye+qZDo54>zhO?x1c8s)C;foi@#KF^tiZVIX&+$GB#M&%BWc`1@1VD zFR$;^Cho3zQ;)+8##q>Q*OC$EB{dM_^wdf~Tc>|t$87>Bf2Fq$=+_on!1L!_+U;F) zNsUQLCZf0`ed(?h`eS*`xWsSSP{ZBp2$0e4hRiRoywuOIQ8RtlOi5;7VrnhYMWe3lZRgqAGfz{} zSxLT4#NV%|Bq3l{kO=+ko%LDTK)5B9DFdKuw?k|*>%R5GVw>t7>)L0sb+f$nbb4kH zfy@+jM^?60Ud}shN(PJbj&Tck!9a`4$%tTwf$mBX3LL|440h78D3Y8nylhL!2x)iy zBfR9Rj_YNs8nMfH@QS~Hl&(!(oo`-#dHYdp`n~qIH?8W&#`}`iV{@hVCFK(Hw$R4m z=c5vsh&XVs(sf1OWhaPx*0;@dZ;V3F)$bkGkjfFaz&AR5?aR!?ra5SFlTGGYx_uM9ik>8hR&m^f$g!Q~kwVx*)?f7&HihN)vsq{G%8=A~`GaBev0N6Z`dec)U z>CeRFW9`@Egq>RphdR^RL*36|UwmL}4s0{M1D-BgSoDh!_ND}J9nmWtsxbF^j$}j z1{INB;bz~wB=0HsZOVll8{{F|oTc^#Q`1~dkMpe1`tgb0Eg}{1>b&U&&)u?w9v$6A zCXayC2h(`};K2TX%vQ*{zPuEc4XuF)y>4q)7xKKwvE3V{cKq?Tk2TZFPIW-+iZY`- z)t1$*0UOO0D$nYwdusd5n&ZKtBi~L-qo?--iS;RAqRce0UP%%pF@=gs>Gy?fEan>x4oGlt-jr-tEb}k=qAV*_ES?9YWmJT zSinF-zt~tzt@9?%g0f9Y7uc3elRwVm>~f{3_^kl6jNF=wcTB8k-cDFVZ&?3CBIVlA zBp_Q3^y8p;b$G~z4%@`!Ow-7srHH0@rUMkPFvU>4gLPJnYAn6+czIB7F?E6@2 z?kil55p4S3o3DSM^XGDA>6AJtgy|X{zZh;>atR4DR7QQbj?;NNTnd`EXEjevL~gip z#NK0$(@F%biGCn?N?jVXqgs{~zS$NYg$t&aDa5uFjyItIVcOb~1LOC3=ypS87_my| zLG1lKbUHWW&8bk5-C#ZJvuDOuADvCPr?bto=HsH&=#SJ2Sw1}Cp6Lu8pM9~qOx%Bk z^pK^|15^@!{ev6-vG4c@4Sb9-gNKLh8@gS8eX4;dI>G$;ra8n_c;MQ}UpL;z4$BS)Feh?=T(=t37v{x)R`P;t(AOD3}QGVVZ5CuB4 zf7M=oA4B*f1@z+)y3DhG6uhtH>Bw|;0poE-zX^o?$ONG-c_gtzjDJ1YUH=l5EyeQ; zefR$rq(|^DX!`eiQGJ7rnT#lJlzsC{9Q=<;&vKMh%fCbJS7VutVWan^x#pvxq4g`t zN$Ug;XXWGJ{MQo(4(KvIzuWbiZx_H%f}9tZFI@ zfA(J=mAfom(Z8wxDJ+4G@G($H1K0JRs_aBdt#ka>c>7P091s3^C3;>s!;v$(%;A51 y-X9bjmDOyA@pv3n4PyYv0Vf>;1 diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/images/华东院logo.png b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/images/华东院logo.png deleted file mode 100644 index 78379c3aa7909187ef78a0bdbbac1c6a7c204818..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131333 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 diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/images/电建logo.png b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/images/电建logo.png deleted file mode 100644 index c11cc4faa5eb528417bc967a4695231de876edc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83868 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 z 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 _?M2qoM4Nm-_7hL$avVn^)d4 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - POWERCHINA - - - - - - - - - {{TITLE}} - - - - - {{SUBTITLE}} - - - - - - - - - {{AUTHOR}} - - - - - 汇报人:{{PRESENTER}} - - - - - {{DATE}} - - - - - - - - - 中国电力建设集团有限公司 POWERCHINA - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/02_chapter.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/02_chapter.svg deleted file mode 100644 index 09f6c9c9..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/02_chapter.svg +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0{{CHAPTER_NUM}} - - - - - 0{{CHAPTER_NUM}} - - - - - - - - - {{CHAPTER_TITLE}} - - - - - {{CHAPTER_SUBTITLE}} - - - - - - - - POWERCHINA · 中国电力建设集团有限公司 - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/02_toc.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/02_toc.svg deleted file mode 100644 index 85842de7..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/02_toc.svg +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 目 录 - - - CONTENTS - - - - - - - - - 01 - - {{TOC_ITEM_1_TITLE}} - {{TOC_ITEM_1_DESC}} - - - - - - 02 - - {{TOC_ITEM_2_TITLE}} - {{TOC_ITEM_2_DESC}} - - - - - - 03 - - {{TOC_ITEM_3_TITLE}} - {{TOC_ITEM_3_DESC}} - - - - - - 04 - - {{TOC_ITEM_4_TITLE}} - {{TOC_ITEM_4_DESC}} - - - - - - 05 - - {{TOC_ITEM_5_TITLE}} - {{TOC_ITEM_5_DESC}} - - - - - - - - {{STAT_1}} - {{STAT_1_LABEL}} - - - - {{STAT_2}} - {{STAT_2_LABEL}} - - - - {{STAT_3}} - {{STAT_3_LABEL}} - - - - - - {{PAGE_NUM}} - - - POWERCHINA - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/03_content.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/03_content.svg deleted file mode 100644 index 066aa337..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/03_content.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - {{CHAPTER_NUM}} - - - {{PAGE_TITLE}} - - - POWERCHINA - - - - - - - - - {{CONTENT_AREA}} - - - (由 Executor 根据实际内容自由布局) - - - - - - - {{PAGE_NUM}} - - - POWERCHINA - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/04_ending.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/04_ending.svg deleted file mode 100644 index 4d7f9d23..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/04_ending.svg +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - POWERCHINA - - - - - {{THANK_YOU}} - - - - - {{THANK_YOU_EN}} - - - - - - - - - - 欢迎批评指正 - - - - - {{AUTHOR}} - - - - - {{CONTACT_INFO}} - - - - - - - 中国电力建设集团有限公司 - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/design_spec.md deleted file mode 100644 index e3612125..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电建/templates/design_spec.md +++ /dev/null @@ -1,208 +0,0 @@ ---- -deck_id: 中国电建 -kind: deck -native_structure_mode: template -summary: Engineering project reports, technical proposal presentations, business negotiations, corporate promotion, annual summaries. -canvas_format: ppt169 -page_count: 5 -primary_color: "#00418D" ---- - -# POWERCHINA (中国电建) Standard Template - Design Specification - -> Suitable for PowerChina (China Power Construction Corporation) project reports, engineering showcases, business negotiations, corporate promotion, and similar scenarios. - ---- - -## I. Template Overview - -| Property | Description | -| -------------- | ---------------------------------------------------------------- | -| **Template Name** | 中国电建 | -| **Use Cases** | Engineering project reports, technical proposal presentations, business negotiations, corporate promotion, annual summaries | -| **Design Tone** | Professional, composed, international, state-owned enterprise style | -| **Theme Mode** | Light theme (white background + POWERCHINA blue accent) | - ---- - -## II. Canvas Specification - -| Property | Value | -| -------------- | ----------------------------- | -| **Format** | Standard 16:9 | -| **Dimensions** | 1280 × 720 px | -| **viewBox** | `0 0 1280 720` | -| **Page Margins** | Left/Right 60px, Top 80px, Bottom 40px | -| **Safe Area** | x: 60-1220, y: 80-680 | - ---- - -## III. Color Scheme - -### Primary Colors (POWERCHINA Brand Colors) - -| Role | Color Value | Notes | -| -------------- | ----------- | ---------------------------------- | -| **POWERCHINA Blue** | `#00418D` | Primary color for title bars, accent blocks, decorative bars | -| **Deep Blue** | `#002B5C` | Chapter page background, gradient dark end | -| **Vibrant Blue** | `#0066CC` | Secondary accent, chart colors | -| **Sky Blue** | `#4A90D9` | Decorative accents, tertiary emphasis | -| **Background White** | `#FFFFFF` | Main page background | -| **Auxiliary Light Gray** | `#F4F6F8` | Secondary content background blocks | - -### Auxiliary Colors (China Red Accents) - -| Role | Color Value | Notes | -| -------------- | ----------- | ---------------------------------- | -| **China Red** | `#C41E3A` | Key data emphasis, decorative accents | -| **Gold** | `#C9A227` | Honors, achievements display | - -### Text Colors - -| Role | Color Value | Usage | -| -------------- | ----------- | ---------------------- | -| **Primary Text** | `#1A1A1A` | Body text, headings | -| **White Text** | `#FFFFFF` | Text on dark backgrounds | -| **Secondary Text** | `#4A5568` | Dimmed chapters, auxiliary descriptions | -| **Light Auxiliary** | `#718096` | Annotations, page numbers, hints | - ---- - -## IV. Typography System - -### Font Stack - -**Font Stack**: `"Microsoft YaHei", "微软雅黑", "SimHei", Arial, sans-serif` - -### Font Size Hierarchy - -| Level | Usage | Size | Weight | -| ----- | ------------------ | ---- | ------- | -| H1 | Cover main title | 48px | Bold | -| H2 | Page heading | 28px | Bold | -| H3 | Section title / Subtitle | 24px | Bold | -| P | Body content | 18px | Regular | -| High | Emphasized data | 36px | Bold | -| Sub | Auxiliary notes | 14px | Regular | - ---- - -## V. Page Structure - -### Common Layout - -| Area | Position/Height | Description | -| ---------- | --------------- | -------------------------------------- | -| **Top** | y=0, h=6px | POWERCHINA blue gradient bar spanning full width | -| **Title Bar** | y=30, h=50px | Chapter number block + Title text + Top-right Logo | -| **Content** | y=100, h=560px | Main content area | -| **Footer** | y=680, h=40px | Page number, company name, bottom decorative line | - -**Required background layer**: Every page retains the template's full-canvas background layer. - ---- - -## VI. Page Types - -### 1. Cover Page (01_cover.svg) - -- Deep blue gradient background + engineering-style diagonal line texture -- Left-side brand blue decorative bar -- Main title + subtitle (white) -- Company English name POWERCHINA -- Bottom red decorative bar - -### 2. Table of Contents (02_toc.svg) - -- White background + left-side blue decorative area -- Supports up to 5 chapters -- Numbered items + vertical line separator design -- Right side can display corporate data - -### 3. Chapter Page (02_chapter.svg) - -- Deep blue gradient background -- Large chapter number -- Chapter title + English subtitle -- Geometric grid decoration - -### 4. Content Page (03_content.svg) - -- White background -- Standard navigation bar -- Flexible content area -- Supports multiple layout patterns - -### 5. Ending Page (04_ending.svg) - -- Deep blue gradient background -- Corporate Logo area -- Thank-you message (Chinese & English) -- Corporate information - ---- - -## VII. SVG Page Roster - -| File | Role | Description | -|------|------|-------------| -| `01_cover.svg` | cover | Title slide; brand/project name + presenter + date | -| `02_chapter.svg` | chapter | Chapter divider page (large number + chapter title) | -| `02_toc.svg` | toc | Table of contents listing major sections | -| `03_content.svg` | content | Main content page; body of the deck | -| `04_ending.svg` | ending | Closing/thank-you page | - -## VIII. Layout Patterns (Recommended) - -### 1. Split Column -- Classic image-text mixed layout: left text / right image, or left image / right text. -- Recommended split ratio: 1:1 or 2:3. - -### 2. Card Grid -- 3-column or 4-column card layout for showcasing project cases or qualifications. -- Card background recommended: auxiliary light gray `#F4F6F8`. - -### 3. Process Flow -- Horizontal timeline or flowchart for displaying project progress. -- POWERCHINA blue as the main axis color, China Red for key milestone markers. - ---- - -## IX. Spacing Guidelines - -| Property | Value | Description | -| -------------- | ----- | ------------------------ | -| **Base Unit** | 8px | All spacing should be multiples of 8px | -| **Module Gap** | 32px | Standard gap between major modules | -| **Card Gap** | 24px | Gap between cards | -| **Inner Padding** | 24px | Padding inside cards | -| **Line Height** | 1.5 | Standard body line height | - ---- - -## X. Placeholder Specification - -| Placeholder | Description | -| -------------------- | ------------------ | -| `{{TITLE}}` | Main title | -| `{{SUBTITLE}}` | Subtitle | -| `{{AUTHOR}}` | Presenting organization | -| `{{PRESENTER}}` | Presenter | -| `{{CHAPTER_NUM}}` | Chapter number | -| `{{PAGE_NUM}}` | Page number | -| `{{DATE}}` | Date | -| `{{CHAPTER_TITLE}}` | Chapter title | -| `{{PAGE_TITLE}}` | Page title | -| `{{CONTENT_AREA}}` | Content area identifier | -| `{{TOC_ITEM_N_TITLE}}` | TOC item title | -| `{{TOC_ITEM_N_DESC}}` | TOC item description | -| `{{THANK_YOU}}` | Thank-you message | -| `{{CONTACT_INFO}}` | Contact information | - ---- - -## XI. Usage Notes (Recommended) - -1. **Logo Adaptation**: Cover and ending pages use inverted (white) Logo; content page upper-right uses color or inverted Logo. -2. **Image Assets**: Ensure the `images/` folder under the template directory contains necessary Logo files. -3. **Fonts**: Recommend installing "Microsoft YaHei" for optimal display. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/01_cover.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/01_cover.svg index bfe13501..ed46cb16 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/01_cover.svg +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/01_cover.svg @@ -1,54 +1,44 @@ - - + + + + - - - - - - - - - - - - - - - - - {{TITLE}} - - - - - {{SUBTITLE}} - - - - - - - - {{AUTHOR}} - - - - - {{AUTHOR_EN}} - - - - + + + + {{TITLE}} + + + {{SUBTITLE}} + + + {{AUTHOR}} + + + {{AUTHOR_EN}} + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/02_chapter.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/02_chapter.svg index 355a09f8..44074fbc 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/02_chapter.svg +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/02_chapter.svg @@ -1,47 +1,41 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - 0{{CHAPTER_NUM}} - - - - - - - - {{CHAPTER_TITLE}} - - - - - {{CHAPTER_SUBTITLE}} - - - - - + + + + + + + + + + {{CHAPTER_NUM}} + + + {{CHAPTER_TITLE}} + + + {{CHAPTER_SUBTITLE}} + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/02_toc.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/02_toc.svg index 573ef4a8..67d9f5a7 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/02_toc.svg +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/02_toc.svg @@ -1,73 +1,114 @@ - - - - - - - - - - - - - 目 录 - - - - - - - - 01 - || - {{TOC_ITEM_1_TITLE}} - {{TOC_ITEM_1_DESC}} - - - - - 02 - || - {{TOC_ITEM_2_TITLE}} - {{TOC_ITEM_2_DESC}} - - - - - 03 - || - {{TOC_ITEM_3_TITLE}} - {{TOC_ITEM_3_DESC}} - - - - - 04 - || - {{TOC_ITEM_4_TITLE}} - {{TOC_ITEM_4_DESC}} - - - - - 05 - || - {{TOC_ITEM_5_TITLE}} - {{TOC_ITEM_5_DESC}} - - - - - {{STAT_NUMBER_1}} - {{STAT_LABEL_1}} - {{STAT_NUMBER_2}} - {{STAT_LABEL_2}} - - - - - - {{PAGE_NUM}} - + + + + + + + + + + + 01 + || + 02 + || + 03 + || + 04 + || + 05 + || + + + + {{PAGE_TITLE}} + + + {{TOC_ITEM_1_TITLE}} + + + {{TOC_ITEM_2_TITLE}} + + + {{TOC_ITEM_3_TITLE}} + + + {{TOC_ITEM_4_TITLE}} + + + {{TOC_ITEM_5_TITLE}} + + + {{CONTENT_AREA}} + + + {{PAGE_NUM}} + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/03_content.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/03_content.svg index 2ed8376f..51e8c45a 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/03_content.svg +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/03_content.svg @@ -1,57 +1,50 @@ - - - - - - - - - - - - - {{CHAPTER_NUM}} - - - {{PAGE_TITLE}} - - - - - - - - - {{CONTENT_AREA}} - - - (由 Executor 根据实际内容自由布局) - - - - - - - - - - - - - {{PAGE_NUM}} + + + + + + + + + + + {{CHAPTER_NUM}} + + + {{PAGE_TITLE}} + + + {{CONTENT_AREA}} + + + {{PAGE_NUM}} + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/04_ending.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/04_ending.svg index 1fddae3f..a70dd7fa 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/04_ending.svg +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/04_ending.svg @@ -1,62 +1,70 @@ - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - {{THANK_YOU}} - - - - - {{THANK_YOU_EN}} - - - - - - - - {{CONTACT_INFO}} - - - - - {{AUTHOR}} - - - - - - {{ENDING_SUBTITLE}} - + + + + + + + + + + + + + + {{THANK_YOU}} + + + {{THANK_YOU_EN}} + + + {{CONTACT_INFO}} + + + {{ENDING_SUBTITLE}} + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/design_spec.md index 76ecd4a7..e1f50f17 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/design_spec.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/design_spec.md @@ -1,214 +1,62 @@ --- deck_id: 中汽研 kind: deck -native_structure_mode: template -summary: Product certification display, evaluation presentations, technology promotion, business visits. -canvas_format: ppt169 -page_count: 5 +category: brand +summary: 中汽研认证展示、技术交流与业务来访场景的深蓝专业模板。 +keywords: [中汽研, 认证, 评测, 技术交流] primary_color: "#004098" +canvas_format: ppt169 +canvas_width: 1280 +canvas_height: 720 +canvas_viewbox: "0 0 1280 720" +source_canvas_width: 1280 +source_canvas_height: 720 +source_viewbox: "0 0 1280 720" +replication_mode: fidelity +native_structure_mode: structured +page_count: 5 --- -# CATARC (中汽研) Standard Template - Design Specification - -> Suitable for CATARC product certification, evaluation & certification, technology showcases, business visits, and similar scenarios. - ---- +# 中汽研 — Design Specification ## I. Template Overview -| Property | Description | -| -------------- | ---------------------------------------------------------- | -| **Template Name** | 中汽研 | -| **Use Cases** | Product certification display, evaluation presentations, technology promotion, business visits | -| **Design Tone** | Professional, authoritative, trustworthy, consulting style | -| **Theme Mode** | Light theme (white background + deep blue accent) | +- 适用于产品认证展示、评测汇报、技术推广和业务来访。 +- 视觉以中汽研深蓝、白底内容页、方形章节编号和简洁网格为识别核心,强调专业、可信和工程秩序。 +- 整套模板使用 CATARC Dark 与 CATARC Light 两个 Master,并提供五个可直接从 PowerPoint 布局库调用的 Layout。 ---- +## II. Color Scheme -## II. Canvas Specification +| Role | Color | Application | +| --- | --- | --- | +| CATARC blue | #004098 | 深色页面背景、章节编号块、结构线 | +| Deep blue | #003B82 | 封面背景 | +| Panel gray | #F8FAFC | 内容承载区 | +| Border gray | #E0E0E0 | 分隔线和面板边界 | +| Primary text | #333333 | 内容页标题和正文 | +| White | #FFFFFF | 深色页面文字与 Master 背景 | -| Property | Value | -| -------------- | ----------------------------- | -| **Format** | Standard 16:9 | -| **Dimensions** | 1280 × 720 px | -| **viewBox** | `0 0 1280 720` | -| **Page Margins** | Left/Right 60px, Top 80px, Bottom 40px | -| **Safe Area** | x: 60-1220, y: 80-680 | +## IV. Signature Design Elements ---- +- 白底内容页使用“蓝色方形章节号 + 左对齐标题 + 右上角 Logo”的稳定页眉。 +- 封面、章节页和结束页保留深蓝底、低透明度圆形与细网格,但删除无内容价值的复杂渐变和动态图片依赖。 +- CATARC Dark Master 统一承载深蓝背景和上下结构线;章节页与结束页各自保留原稿中的圆形几何,封面不继承圆形。CATARC Light Master 统一承载白底、章节号方块、页眉 Logo、分隔线和底部蓝线。 +- 目录页延续数字与双竖线的行式导航,并保留右侧独立数据对象区。 +- 通用内容对象从框体左上角开始;封面、章节页、结束页以及小型章节号属于短焦点内容,允许在完整占位框中居中。 -## III. Color Scheme +## V. Page Roster -### Primary Colors +| File | Master | Layout key | PowerPoint picker name | Visual character | Reusable slots | +| --- | --- | --- | --- | --- | --- | +| (01_cover.svg) | CATARC Dark | cover | Cover | 深蓝背景、居中大型 Logo 与标题簇 | 标题、副标题、单位、英文单位 | +| (02_toc.svg) | CATARC Light | agenda | Agenda | 数字双竖线目录、右侧数据面板 | 页面标题、五个目录项、数据对象、页码 | +| (02_chapter.svg) | CATARC Dark | section | Section Header | 深蓝章节页、居中章节号和标题 | 章节号、章节标题、章节副标题 | +| (03_content.svg) | CATARC Light | content | Title and Content | 方形章节号页眉与开放内容面板 | 章节号、页面标题、内容对象、页码 | +| (04_ending.svg) | CATARC Dark | closing | Closing | 深蓝网格背景、居中 Logo 与结束语 | 结束标题、英文副标题、联系信息、页脚 | -| Role | Color Value | Notes | -| -------------- | ----------- | -------------------------------- | -| **Primary Deep Blue** | `#004098` | Title bar, navigation bar, chapter number blocks, decorative bars | -| **Background White** | `#FFFFFF` | Main page background | -| **Auxiliary Light Gray** | `#F5F5F5` | Secondary content background blocks | -| **Border Gray** | `#E0E0E0` | Dividers, borders | -| **Accent Red** | `#CC0000` | Key information highlight | +## VI. Assets -### Text Colors - -| Role | Color Value | Usage | -| -------------- | ----------- | ---------------------- | -| **Primary Text** | `#333333` | Body text, headings | -| **White Text** | `#FFFFFF` | Text on dark backgrounds | -| **Secondary Text** | `#666666` | Dimmed chapters, auxiliary descriptions | -| **Light Auxiliary** | `#999999` | Annotations, page numbers, hints | - -### Functional Colors - -| Usage | Color Value | Description | -| ---------- | ----------- | -------------- | -| **Success** | `#4CAF50` | Pass / Certified | -| **Warning** | `#CC0000` | Failed / Attention | - ---- - -## IV. Typography System - -### Font Stack - -**Font Stack**: `"Microsoft YaHei", "微软雅黑", "SimHei", Arial, Calibri, sans-serif` - -### Font Size Hierarchy - -| Level | Usage | Size | Weight | -| ----- | ------------------ | ---- | ------- | -| H1 | Cover main title | 48px | Bold | -| H2 | Page heading | 28px | Bold | -| H3 | Section title / Subtitle | 24px | Bold | -| P | Body content | 18px | Regular | -| High | Emphasized data | 36px | Bold | -| Sub | Auxiliary notes | 14px | Regular | - ---- - -## V. Page Structure - -### Common Layout - -| Area | Position/Height | Description | -| ---------- | --------------- | -------------------------------------- | -| **Top** | y=0, h=4px | Deep blue bar spanning full width | -| **Title Bar** | y=30, h=50px | Chapter number block + Title text + Top-right Logo | -| **Content** | y=100, h=560px | Main content area | -| **Footer** | y=680, h=40px | Page number (right-aligned), bottom decorative line | - -### Navigation Design - -- **Top Decorative Line**: Deep blue (`#004098`), height 4px, spanning full width -- **Bottom Decorative Line**: Deep blue (`#004098`), height 4px, y=716 -- **Title Bar** (y=30): - - Chapter number block: Deep blue square (50×50px), white number/text centered - - Title text: 20px from number block, 28px font size, `#333333` - - Top-right Logo: Fixed at x=1107, size 113×50px - ---- - -## VI. Page Types - -### 1. Cover Page (01_cover.svg) - -- Supports background image (AI-generated / user-provided) -- Semi-transparent overlay for text readability -- Large centered Logo -- Main title + subtitle -- Organization name (Chinese & English) - -### 2. Table of Contents (02_toc.svg) - -- Double vertical line `||` separator design -- Supports up to 5 chapters -- Left decorative vertical line -- Optional statistics display area on the right - -### 3. Chapter Page (02_chapter.svg) - -- Deep blue gradient background -- Large chapter number -- Chapter title + English subtitle - -### 4. Content Page (03_content.svg) - -- White background -- Standard navigation bar -- Flexible content area -- Supports multiple layout patterns - -### 5. Ending Page (04_ending.svg) - -- Deep blue solid background -- Centered Logo -- Thank-you message -- Organization information - ---- - -## VII. SVG Page Roster - -| File | Role | Description | -|------|------|-------------| -| `01_cover.svg` | cover | Title slide; brand/project name + presenter + date | -| `02_chapter.svg` | chapter | Chapter divider page (large number + chapter title) | -| `02_toc.svg` | toc | Table of contents listing major sections | -| `03_content.svg` | content | Main content page; body of the deck | -| `04_ending.svg` | ending | Closing/thank-you page | - -## VIII. Layout Patterns (Recommended) - -| Pattern | Use Cases | -| -------------------- | ------------------------------ | -| **Single Column Center** | Cover, conclusion, key points | -| **Left-Right Split (5:5)** | Comparison display | -| **Left-Right Split (4:6)** | Image-text mixed layout | -| **Top-Bottom Split** | Process description, standards list | -| **Three-Column Cards** | Project listings | -| **Matrix Grid** | Category display | -| **Table** | Data comparison, specification lists | - ---- - -## IX. Spacing Guidelines - -| Element | Value | -| -------------- | ------ | -| Card gap | 24px | -| Content block gap | 32px | -| Card padding | 24px | -| Card border radius | 8px | -| Icon-to-text gap | 12px | - ---- - -## X. Placeholder Specification - -Templates use `{{PLACEHOLDER}}` format. Common placeholders: - -| Placeholder | Description | -| -------------------- | ------------------ | -| `{{TITLE}}` | Main title | -| `{{SUBTITLE}}` | Subtitle | -| `{{AUTHOR}}` | Author / Organization (Chinese) | -| `{{AUTHOR_EN}}` | Author / Organization (English) | -| `{{PAGE_TITLE}}` | Page title | -| `{{CHAPTER_NUM}}` | Chapter number | -| `{{PAGE_NUM}}` | Page number | -| `{{TOC_ITEM_N_TITLE}}` | TOC item title | -| `{{TOC_ITEM_N_DESC}}` | TOC item description | -| `{{THANK_YOU}}` | Thank-you message | -| `{{CONTACT_INFO}}` | Primary contact info | -| `{{LOGO_LARGE}}` | Large Logo filename | -| `{{LOGO_HEADER}}` | Header Logo filename | -| `{{COVER_BG_IMAGE}}` | Cover background image filename | - ---- - -## XI. Usage Notes (Recommended) - -1. **Template Deployment**: Copy the template to your project directory. -2. **Asset Replacement**: Replace `大型 logo.png` (592×238) and `右上角 logo.png` (113×50) in the `images` directory. -3. **Content Generation**: Select appropriate page templates based on content needs, and replace content using `{{}}` placeholders. -4. **SVG Generation**: Generate final SVG files via automation scripts. +| File | Intended usage | +| --- | --- | +| 大型 logo.png | 封面和结束页主标识 | +| 右上角 logo.png | 目录页和内容页页眉标识 | diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/images/cover_bg.png b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/images/cover_bg.png deleted file mode 100644 index ab7c9d9858c279c7c06a8eceaefc756881ed7aa7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 122044 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

2$VG2A0@TwH(9x3s7TR5@u)O# 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 diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/images/logo_dark.png b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/images/logo_dark.png deleted file mode 100644 index 773dfa9646d1accff576cf13c652615f26baf333..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22493 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 TrvkJp00000NkvXXu0mjf1%yhy diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/images/logo_white.png b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/images/logo_white.png deleted file mode 100644 index 70762feb299b2c1c79773ab548a0fe292c7817ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14066 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 diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/images/page_header_bg.png b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/images/page_header_bg.png deleted file mode 100644 index dd61719134e065c0c3ca9e6d3e918def45aba1d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25166 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 MS9@0Q^i|OR16nf4y8r+H diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/images/ref_content_bg.png b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/images/ref_content_bg.png deleted file mode 100644 index 0db4df729d003da7d4049f502ff43e085e7e047b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56809 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 I - - - - - - - - - - - - - - {{TITLE}} - - - {{SUBTITLE}} - - - {{AUTHOR}} - - - {{DATE}} - - - {{TAGLINE}} - - - {{BRAND_LINE}} - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/02_chapter.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/02_chapter.svg deleted file mode 100644 index 349070c8..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/02_chapter.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - {{CHAPTER_NUM}} - - - {{CHAPTER_TITLE}} - - - {{CHAPTER_DESC}} - - - - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/02_toc.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/02_toc.svg deleted file mode 100644 index 9b43633b..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/02_toc.svg +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - 目录 / CONTENTS - - - - - - - {{CONTENT_AREA}} - - - Content Area: 1138 × 540 px - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/03_content.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/03_content.svg deleted file mode 100644 index 7985cf26..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/03_content.svg +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - {{PAGE_TITLE}} - - - - - - {{SECTION_NAME}} - - - - - {{KEY_MESSAGE}} - - - - - - - - - - - - {{CONTENT_AREA}} - - - Content Area: 1138 × 404 px - - - - - - 数据来源:{{SOURCE}} - - - {{PAGE_NUM}} - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/04_ending.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/04_ending.svg deleted file mode 100644 index 93a13184..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/04_ending.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - {{THANK_YOU}} - - - {{ENDING_SUBTITLE}} - - - {{CLOSING_MESSAGE}} - - - - - - {{CONTACT_NAME}} - - - {{DEPARTMENT}} - - - - {{CONTACT_EMAIL}} - - - {{CONTACT_PHONE}} - - - - - {{BRAND_LINE}} - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/design_spec.md deleted file mode 100644 index 67021daf..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/招商银行/templates/design_spec.md +++ /dev/null @@ -1,234 +0,0 @@ ---- -deck_id: 招商银行 -kind: deck -native_structure_mode: template -summary: 交易银行产品介绍、销售收款方案汇报、客户案例拆解、分行培训材料. -canvas_format: ppt169 -page_count: 5 -primary_color: "#C8152D" ---- - -# China Merchants Bank Transaction Banking - Design Specification - -## I. Template Overview - -| Property | Description | -| --- | --- | -| **Template Name** | 招商银行 | -| **Display Name** | China Merchants Bank Transaction Banking Template | -| **Use Cases** | 交易银行产品介绍、销售收款方案汇报、客户案例拆解、分行培训材料 | -| **Design Tone** | Brand-consistent, structured, product-focused, refined finance | -| **Theme Mode** | Hybrid theme (brand-red cover/chapter/ending + light content pages) | - -Reference slides read before generation: `1, 2, 3, 4, 6, 9, 11, 13, 16, 18`. - -## II. Canvas Specification - -| Property | Value | -| --- | --- | -| **Format** | Standard 16:9 | -| **Dimensions** | 1280 × 720 px | -| **viewBox** | `0 0 1280 720` | -| **Safe Margins** | 56px left/right, 48px top, 40px bottom | -| **Primary Content Area** | x: 72-1216, y: 140-640 | - -## III. Color Scheme - -| Role | Color Value | Usage | -| --- | --- | --- | -| **Brand Red** | `#C8152D` | Header strips, emphasis, chapter anchor | -| **Deep Red** | `#8F0F1B` | Dark-page overlay and structural depth | -| **Signal Red** | `#E26A74` | Fine divider accents on cover | -| **Finance Blue** | `#2175D9` | Case-study secondary emphasis | -| **Dark Text** | `#1F1F1F` | Main titles and core copy | -| **Medium Gray** | `#666666` | Secondary copy | -| **Light Gray** | `#E9E9E9` | Dividers and boundary hints | -| **White** | `#FFFFFF` | Background and reverse text | - -## IV. Typography System - -| Level | Usage | Size | Weight | -| --- | --- | --- | --- | -| **H1** | Cover title | 54px | Bold | -| **H2** | Chapter title | 46px | Bold | -| **H3** | Content title | 26px | Bold | -| **H4** | TOC / card title | 20px | Bold | -| **Body** | Paragraph text | 16px | Regular | -| **Caption** | Metadata / footer | 12px | Regular | -| **Display Number** | Chapter numeral | 220px | Bold | - -**Font Stack**: `"Microsoft YaHei", "PingFang SC", Arial, sans-serif` - -## V. Page Structure - -### Common Layout - -| Area | Description | -| --- | --- | -| **Header Strip** | Red brand strip with logo, used on light pages | -| **Title Zone** | Left-aligned title and short key message | -| **Content Body** | Open layout with only light boundary hints | -| **Footer** | Thin divider, section/source/page number | - -### Design DNA - -1. Reuse the PPT's bank-red brand language, but simplify heavy PPT export artifacts into clean vector geometry. -2. Keep cover / chapter / ending pages visually strong and brand-led. -3. Keep content pages bright and practical for data, process, and case-study layouts. -4. Preserve a secondary finance-blue accent to support comparison and case storytelling. -5. Maintain content coverage ≤ 60%, ensuring visual "breathing room" on data-heavy pages. -6. Use structured layouts (cards, grids, process flows) to organize financial data clearly. - -## VI. Page Types - -### 1. Cover Page (`01_cover.svg`) - -- Uses the imported cover background asset `cover_bg.png` -- Centered white typography with restrained divider lines -- Suitable for title, subtitle, presenter, and date - -### 2. Table of Contents (`02_toc.svg`) - -- Light page with red top strip and logo -- Two-column indexed list for up to four agenda items -- Red numerals + dark text for fast scanning - -### 3. Chapter Page (`02_chapter.svg`) - -- Full-brand dark red background -- Large translucent chapter numeral in the background -- Left-aligned title and short chapter description - -### 4. Content Page (`03_content.svg`) - -- Light page with a narrow red header strip and right-aligned white logo -- Page title, section label, key message line, and open body region -- Footer includes section name, source, and page number - -### 5. Ending Page (`04_ending.svg`) - -- Reuses the cover background asset -- Centered closing message and compact contact card -- Suitable for formal client-facing endings - -## VII. SVG Page Roster - -| File | Role | Description | -|------|------|-------------| -| `01_cover.svg` | cover | Title slide; brand/project name + presenter + date | -| `02_chapter.svg` | chapter | Chapter divider page (large number + chapter title) | -| `02_toc.svg` | toc | Table of contents listing major sections | -| `03_content.svg` | content | Main content page; body of the deck | -| `04_ending.svg` | ending | Closing/thank-you page | - -## VIII. Layout Modes - -| Mode | Recommendation | -| --- | --- | -| **Process / Flow** | Use full-width body area with 3-6 horizontal stages | -| **Case Study** | Use split columns or a left-right evidence / solution structure | -| **Product Feature** | Use a short key message on top and modular cards below | -| **Agenda / Sectioning** | Use TOC or chapter page instead of improvising layout headers | - -## IX. Spacing Specification - -| Property | Value | -| --- | --- | -| **Base Unit** | 8px | -| **Module Gap** | 24px | -| **Card Gap** | 20px | -| **Title to Body** | 44px | -| **Footer Offset** | 32px from bottom | - -## X. Placeholder Specification - -| Placeholder | Description | -| --- | --- | -| `{{TITLE}}` | Cover main title | -| `{{SUBTITLE}}` | Cover subtitle | -| `{{DATE}}` | Cover date | -| `{{AUTHOR}}` | Cover presenter / organization | -| `{{TAGLINE}}` | Cover tagline (e.g. product/service line) | -| `{{BRAND_LINE}}` | Cover bottom brand attribution line | -| `{{CHAPTER_NUM}}` | Chapter number | -| `{{CHAPTER_TITLE}}` | Chapter title | -| `{{CHAPTER_DESC}}` | Chapter description | -| `{{PAGE_TITLE}}` | Content page title | -| `{{KEY_MESSAGE}}` | Content page key message | -| `{{CONTENT_AREA}}` | Content page body placeholder | -| `{{SECTION_NAME}}` | Section label / footer section | -| `{{SOURCE}}` | Source text | -| `{{PAGE_NUM}}` | Page number | -| `{{TOC_ITEM_1_TITLE}}` | TOC item 1 title | -| `{{TOC_ITEM_1_DESC}}` | TOC item 1 description | -| `{{TOC_ITEM_2_TITLE}}` | TOC item 2 title | -| `{{TOC_ITEM_2_DESC}}` | TOC item 2 description | -| `{{TOC_ITEM_3_TITLE}}` | TOC item 3 title | -| `{{TOC_ITEM_3_DESC}}` | TOC item 3 description | -| `{{TOC_ITEM_4_TITLE}}` | TOC item 4 title | -| `{{TOC_ITEM_4_DESC}}` | TOC item 4 description | -| `{{TOC_FOOTER}}` | TOC page footer description | -| `{{THANK_YOU}}` | Ending main message | -| `{{ENDING_SUBTITLE}}` | Ending subtitle | -| `{{CLOSING_MESSAGE}}` | Ending supporting sentence | -| `{{CONTACT_NAME}}` | Ending contact person name | -| `{{DEPARTMENT}}` | Ending department name | -| `{{CONTACT_EMAIL}}` | Ending email address | -| `{{CONTACT_PHONE}}` | Ending phone number | - -## XI. Asset Specification - -### Core Assets - -| Asset | Purpose | -| --- | --- | -| `cover_bg.png` | Cover / ending brand background (dark pages) | -| `logo_white.png` | White brand logo for red and dark pages | -| `logo_dark.png` | 「招商银行 \| 公司金融」dark logo for light page headers | - -### Optional Assets - -| Asset | Purpose | -| --- | --- | -| `page_header_bg.png` | Full-page header background reference (red accent + logo) | -| `logo_crm_banner.png` | 「招商银行 \| CRM 4.0」red banner (product-specific, use when applicable) | -| `ref_content_bg.png` | Content page reference layout (with building illustration, for design reference only) | - -### Usage Rule - -Core assets are wired into SVG templates. `logo_dark.png` is used on light pages (TOC, content); `logo_white.png` and `cover_bg.png` on dark pages (cover, chapter, ending). Optional assets are available for project-specific customization. - -- Keep bundled image assets semantic and minimal. -- Reconstruct editable template geometry instead of embedding fragments exported from PowerPoint. - -## XII. Chart Specifications - -### Recommended Chart Dimensions - -| Chart Type | Recommended Size | -| --- | --- | -| Bar chart | 500-700 × 400px | -| Pie chart | 300-400px diameter | -| Data card | 160 × 120px | -| Process flow | Full width, 100-140px height | -| Comparison table | 1100 × 300-400px | - -### Chart Color Palette - -| Usage | Colors | -| --- | --- | -| Primary series | `#C8152D`, `#E26A74`, `#8F0F1B` | -| Secondary series | `#2175D9`, `#5A9FE6` | -| Positive indicator | `#27AE60` | -| Negative indicator | `#E74C3C` | -| Neutral | `#666666` | - -## XIII. Usage Instructions - -1. Copy the template directory to the project `templates/` folder -2. Read this design specification to understand the visual system -3. Select the appropriate page template for each slide -4. Replace `company_finance_header.png` if the project is not CRM-specific -5. Mark content to be replaced using `{{PLACEHOLDER}}` format -6. Prioritize data charts and structured layouts; keep text concise -7. Generate final SVGs through the Executor role diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/images/重庆大学logo.png b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/images/重庆大学logo.png deleted file mode 100644 index 21899974fd3552f72b3bf26e4608e9a902ed7fbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12302 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 z 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

quThbRh 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 diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/01_cover.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/01_cover.svg deleted file mode 100644 index 9db14ee0..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/01_cover.svg +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CQU - - - - {{TITLE}} - - - {{SUBTITLE}} - - - - - - - - - 答辩人 - {{AUTHOR}} - - - - 指导老师:{{ADVISOR}} - - - {{INSTITUTION}} - - - - {{DATE}} - - - - - - - - - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/02_chapter.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/02_chapter.svg deleted file mode 100644 index 058304ed..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/02_chapter.svg +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - {{CHAPTER_NUM}} - - - - - - CHAPTER - - - {{CHAPTER_NUM}} - - - - - - {{CHAPTER_TITLE}} - - - {{CHAPTER_DESC}} - - - - - - - - - - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/02_toc.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/02_toc.svg deleted file mode 100644 index 28047c0c..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/02_toc.svg +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - {{TOC_TITLE}} - - - - - - - - - 01 - - {{TOC_ITEM_1_TITLE}} - {{TOC_ITEM_1_DESC}} - - - 02 - - {{TOC_ITEM_2_TITLE}} - {{TOC_ITEM_2_DESC}} - - - 03 - - {{TOC_ITEM_3_TITLE}} - {{TOC_ITEM_3_DESC}} - - - 04 - - {{TOC_ITEM_4_TITLE}} - {{TOC_ITEM_4_DESC}} - - - 05 - - {{TOC_ITEM_5_TITLE}} - {{TOC_ITEM_5_DESC}} - - - 06 - - {{TOC_ITEM_6_TITLE}} - {{TOC_ITEM_6_DESC}} - - - - - - 目录 · CONTENTS - - - - {{PAGE_NUM}} - - - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/03_content.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/03_content.svg deleted file mode 100644 index 1d5454e8..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/03_content.svg +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - {{PAGE_TITLE}} - - - - - - - - - - - 核心观点 - {{KEY_MESSAGE}} - - - - {{CONTENT_AREA}} - - - - - - - - - 数据来源:{{SOURCE}} - - - {{SECTION_NAME}} - - - - {{PAGE_NUM}} - - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/04_ending.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/04_ending.svg deleted file mode 100644 index 1bc4ed66..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/04_ending.svg +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{THANK_YOU}} - - - {{ENDING_SUBTITLE}} - - - - - - - - - - - - - {{CONTACT_INFO}} - {{EMAIL}} - - - {{COPYRIGHT}} - - - {{PAGE_NUM}} - - - CQU - - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/design_spec.md deleted file mode 100644 index 00ab14c9..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/重庆大学/templates/design_spec.md +++ /dev/null @@ -1,235 +0,0 @@ ---- -deck_id: 重庆大学 -kind: deck -native_structure_mode: template -summary: Academic defense, research reports, teaching presentations, scholarly exchange. -canvas_format: ppt169 -page_count: 5 -primary_color: "#006BB7" ---- - -# Chongqing University (重庆大学) Template - Design Specification - -> A distinctive design blending the layered imagery of the Mountain City with modern academic elegance. - ---- - -## I. Template Overview - -| Property | Description | -| ------------------ | -------------------------------------------------------------------- | -| **Template Name** | Chongqing University (重庆大学) | -| **Use Cases** | Academic defense, research reports, teaching presentations, scholarly exchange | -| **Design Tone** | Academically grounded · Mountain City charm · Modern minimalism | -| **Design Inspiration** | Chongqing's layered terrain + the gravitas of historic campus buildings + modern academic professionalism | - -### Design Features - -1. **Layered Geometry**: Diagonal color blocks simulate the terraced landscape of the Mountain City, breaking away from traditional rectangular layouts -2. **Asymmetric Aesthetics**: Left-heavy visual balance guides reading focus -3. **Gradient Color Bands**: Deep-to-light transitions symbolize the journey from a rich history to a bright future -4. **Wave Patterns**: Abstract Yangtze River / Jialing River water elements - ---- - -## II. Canvas Specification - -| Property | Value | -| ------------------ | ----------------------------- | -| **Format** | Standard 16:9 | -| **Dimensions** | 1280 × 720 px | -| **viewBox** | `0 0 1280 720` | -| **Page Margins** | Left/right 60px, top/bottom 40px | -| **Content Safe Area** | x: 60-1220, y: 100-660 | - ---- - -## III. Color Scheme - -### Primary Colors (Extracted from Logo) - -| Role | Value | Notes | -| ------------------ | ----------- | -------------------------------------------- | -| **CQU Blue** | `#006BB7` | Emblem primary color; header, titles, main elements | -| **Deep Blue** | `#004A82` | Chapter page background, emphasis areas | -| **Sky Blue** | `#3A9BD9` | Accent color, gradient endpoint | -| **Cloud Blue** | `#E3F2FD` | Light background, card base color | -| **Dawn Gold** | `#D4A84B` | Decorative accents, highlights (symbolizing brightness) | -| **Background White**| `#FAFCFF` | Subtly blue-tinted pure white | - -### Text Colors - -| Role | Value | Usage | -| ------------------ | ----------- | ------------------------ | -| **Dark Ink Text** | `#1A2E44` | Main titles, heading text | -| **Primary Text** | `#333D4A` | Body content | -| **Secondary Text** | `#6B7B8C` | Captions, annotations | -| **White Text** | `#FFFFFF` | Text on dark backgrounds | - -### Gradient Scheme - -``` -Primary gradient: #004A82 → #006BB7 → #3A9BD9 (deep → light, used for background diagonal cuts) -Gold gradient: #C49A3D → #D4A84B → #E8C675 (decorative use) -``` - ---- - -## IV. Typography System - -### Font Stack - -**Font Stack**: `"Microsoft YaHei", "微软雅黑", "PingFang SC", Arial, sans-serif` - -### Font Size Hierarchy - -| Level | Usage | Size | Weight | Notes | -| ----- | ------------------ | ---- | ------- | ------------------ | -| H1 | Cover main title | 48px | Bold | Grand and dignified | -| H2 | Page title | 26px | Bold | | -| H3 | Chapter title | 44px | Bold | | -| H4 | Card title | 22px | Bold | | -| P | Body content | 17px | Regular | | -| High | Emphasized data | 32px | Bold | | -| Sub | Notes/sources | 13px | Regular | | -| XS | Page number/copyright | 11px | Regular | | - ---- - -## V. Core Visual Elements - -### 1. Diagonal Color Blocks (Mountain City Layers) - -The template's signature design uses diagonally divided color blocks to simulate the layered terrain of the Mountain City: - -``` -Cover: Large deep-blue diagonal block in the lower-left corner (approx. 40% of area) -Chapter page: Full-screen deep blue + light diagonal accent in the upper-right -Content page: Small diagonal accent strip at the top -``` - -### 2. Wave Patterns (Two Rivers Imagery) - -Abstract curves symbolizing the Yangtze and Jialing Rivers: - -```xml - -``` - -### 3. Light Dot Decorations (City Lights) - -Small circle elements representing the nighttime lights of the Mountain City: - -```xml - -``` - ---- - -## VI. Page Types - -### 1. Cover Page (01_cover.svg) - -**Layout Structure**: -- Upper-right area: Logo (using logo.png) -- Center-left: Main title + subtitle -- Lower-left corner: Large diagonal deep-blue color block (extending from lower-left to upper-right) -- Bottom: Presenter info, date -- Decorations: Wave patterns + gold light dots - -### 2. Chapter Page (02_chapter.svg) - -**Layout Structure**: -- Full-screen deep blue background -- Upper-right: Diagonal light area (sky blue gradient) -- Left: Large chapter number (semi-transparent) -- Center-left: Chapter title (white) -- Bottom: Gold decorative line + Logo (white version) - -### 3. Content Page (03_content.svg) - -**Layout Structure**: -- Top: Diagonal blue accent strip (approx. 80px height, higher on left, lower on right) -- On the accent strip: Page title + Logo -- Body: White content area (flexible layout) -- Left: Thin gold decorative line -- Bottom: Clean footer + wave pattern - -### 4. Ending Page (04_ending.svg) - -**Layout Structure**: -- Center: Large-sized Logo -- Below logo: Thank-you message -- Bottom diagonal blue area: Contact information -- Decorations: Wave patterns + gold light dots - -### 5. Table of Contents (02_toc.svg) - -**Layout Structure**: -- Top diagonal accent strip + title -- Left: Large numeric indices (vertically arranged, with gold accents) -- Right: TOC item text -- Bottom: Wave decoration - ---- - -## VII. SVG Page Roster - -| File | Role | Description | -|------|------|-------------| -| `01_cover.svg` | cover | Title slide; brand/project name + presenter + date | -| `02_chapter.svg` | chapter | Chapter divider page (large number + chapter title) | -| `02_toc.svg` | toc | Table of contents listing major sections | -| `03_content.svg` | content | Main content page; body of the deck | -| `04_ending.svg` | ending | Closing/thank-you page | - -## VIII. Logo Usage Guidelines - -| File | Applicable Context | Notes | -|------|-------------------|-------| -| `重庆大学logo.png` | Light/white backgrounds | Blue version | -| `重庆大学logo2.png` | Dark/blue backgrounds | White version | - -**Recommended Logo Sizes**: -- Cover page: Width 280-320px -- Content page header: Width 160-200px -- Ending page: Width 320-400px - -Use the packaged university logo assets through the standard project image pipeline. - ---- - -## IX. Spacing Specification - -| Element | Value | -| -------------------- | ---------- | -| Page margins | 60px | -| Content block spacing | 28px | -| Card inner padding | 24px | -| Card border radius | 12px | -| Diagonal cut angle | Approx. 8-12° | - ---- - -## X. Placeholder Specification - -| Placeholder | Description | -| -------------------- | ---------------------- | -| `{{TITLE}}` | Main title | -| `{{SUBTITLE}}` | Subtitle | -| `{{AUTHOR}}` | Presenter name | -| `{{ADVISOR}}` | Thesis advisor | -| `{{INSTITUTION}}` | College/Institution | -| `{{DATE}}` | Date | -| `{{PAGE_TITLE}}` | Page title | -| `{{CHAPTER_NUM}}` | Chapter number | -| `{{CHAPTER_TITLE}}` | Chapter title | -| `{{CHAPTER_DESC}}` | Chapter description | -| `{{KEY_MESSAGE}}` | Key message | -| `{{CONTENT_AREA}}` | Content area | -| `{{PAGE_NUM}}` | Page number | -| `{{THANK_YOU}}` | Thank-you message | -| `{{CONTACT_INFO}}` | Contact information | -| `{{TOC_ITEM_N_TITLE}}` | TOC item title | -| `{{TOC_ITEM_N_DESC}}` | TOC item description | diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/design_spec_reference.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/design_spec_reference.md index 3438a601..4b9acaed 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/design_spec_reference.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/design_spec_reference.md @@ -250,6 +250,8 @@ Catalog read: 76 templates > **Audit rule**: `Summary-quote` must be copy-pasted verbatim — paraphrasing breaks the audit. Every template name listed must `grep` cleanly inside `charts_index.json` (so misspellings/inventions fail). If fewer than 3 viz pages exist, list what exists and note "fewer than 3 viz pages"; runners-up still required for each page that does exist. +> **Native-preset candidates → append to `Usage`**: for a page already in this list, when its content calls for a literal stock PowerPoint shape (chevron, block arrow, standard flowchart node, callout, banner, star — judged from the page plan, not a template's name), append a candidate note to that page's `Usage`, e.g. `…usage…; native-preset candidate: chevron; Executor applies executor-base §3.0`. The Executor still selects the exact preset, frame, and paint. See [`strategist.md`](../references/strategist.md) Template Match. + --- ## VIII. Image Resource List (if needed) @@ -306,7 +308,7 @@ Catalog read: 76 templates ## IX. Content Outline -> **Native Layout boundary**: Each `Layout` line below describes visual composition intent and feeds the planning-time structured mapping. Before SVG generation, Strategist writes the Master roster and exactly one ` | | ` row per page. Free-design/brand-only pages use that structure from their first draft; template pages also select an input prototype through `page_layouts`. Strict preserves the prototype contract. Adaptive keeps its Master and may assign a new Layout key during page authoring only when fixed Layout atoms or slot topology/bounds change. Legacy prototypes first run [`restore-pptx-structure`](../workflows/restore-pptx-structure.md); no deferred distillation or immediate-compatibility fallback exists. +> **Native Layout boundary**: Each `Layout` line below always describes visual composition intent. On free-design and brand-only routes, it does not create native Master/Layout identity: `spec_lock.md` uses `pptx_structure.mode: flat`, omits `pptx_masters` / `pptx_layouts` / `page_pptx_layouts` / `page_layouts`, and every SVG object stays Slide-local. Export materializes one clean project-owned Master plus one Blank Layout from the current lock, removes stock content placeholders/Layout inventory, and retains only the standard date/footer/slide-number capability hooks. Deck/layout template routes use `mode: structured`: Strategist writes each unique Master/Layout definition once, assigns every page through `page_pptx_layouts`, and selects its authoring prototype through `page_layouts`. Strict preserves the prototype contract. Adaptive keeps its Master and may define and assign a new Layout key during page authoring only when fixed Layout atoms or slot topology/bounds change. Legacy prototypes first run [`restore-pptx-structure`](../workflows/restore-pptx-structure.md); no deferred distillation or immediate-compatibility fallback exists. ### Part 1: [Chapter Name] diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/01_cover.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/01_cover.svg deleted file mode 100644 index 07b45bd4..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/01_cover.svg +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - {{LOGO}} - - - - - - {{TITLE}} - - - - - {{SUBTITLE}} - - - - - - - - - 答辩人:{{AUTHOR}} - - - 指导老师:{{ADVISOR}} - - - {{INSTITUTION}} - - - - - - {{DATE}} - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/02_chapter.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/02_chapter.svg deleted file mode 100644 index 8f5e63ce..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/02_chapter.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - {{CHAPTER_NUM}} - - - - - {{CHAPTER_TITLE}} - - - - - {{CHAPTER_DESC}} - - - - - - - - {{TITLE}} - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/02_toc.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/02_toc.svg deleted file mode 100644 index 4301801d..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/02_toc.svg +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - 目 录 - - - - - {{LOGO}} - - - - - - - - - - 01 - {{TOC_ITEM_1_TITLE}} - {{TOC_ITEM_1_DESC}} - - - - - 02 - {{TOC_ITEM_2_TITLE}} - {{TOC_ITEM_2_DESC}} - - - - - 03 - {{TOC_ITEM_3_TITLE}} - {{TOC_ITEM_3_DESC}} - - - - - 04 - {{TOC_ITEM_4_TITLE}} - {{TOC_ITEM_4_DESC}} - - - - {{TOC_ITEM_5_TITLE}} - - - - {{TOC_ITEM_6_TITLE}} - - - - {{PAGE_NUM}} - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/03_content.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/03_content.svg deleted file mode 100644 index 7180d958..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/03_content.svg +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - {{SECTION_NUM}} {{PAGE_TITLE}} - - - - - - {{LOGO}} - - - - - - - {{KEY_MESSAGE}} - - - - - - - - {{CONTENT_AREA}} - - - - - 可用布局:单栏、双栏、图文混排、卡片网格、时间线等 - - - - - - 数据来源:{{SOURCE}} - - - {{SECTION_NAME}} - - - {{PAGE_NUM}} - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/04_ending.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/04_ending.svg deleted file mode 100644 index 75047dbc..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/04_ending.svg +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - {{LOGO}} - - - - - - {{THANK_YOU}} - - - - - {{ENDING_SUBTITLE}} - - - - - - - - - - - - {{CONTACT_INFO}} - - - {{EMAIL}} - - - {{INSTITUTION}} - - - - - - {{COPYRIGHT}} - - - {{PAGE_NUM}} - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/design_spec.md deleted file mode 100644 index b1ae9d61..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/academic_defense/templates/design_spec.md +++ /dev/null @@ -1,216 +0,0 @@ ---- -layout_id: academic_defense -kind: layout -native_structure_mode: template -summary: Thesis defense, academic presentations, research progress reports, grant applications. -canvas_format: ppt169 -page_count: 5 -page_types: [cover, toc, chapter, content, ending] ---- - -# Academic Defense Template - Design Specification - -> Suitable for academic thesis defense, research presentations, graduation project showcases, and similar scenarios. - ---- - -## I. Template Overview - -| Property | Description | -| -------------- | ------------------------------------------------------ | -| **Template Name** | academic_defense | -| **Use Cases** | Thesis defense, academic presentations, research progress reports, grant applications | -| **Design Tone** | Professional, rigorous, research-oriented, clear hierarchy | -| **Theme Mode** | Light theme (white background + dark blue title bar) | - ---- - -## II. Canvas Specification - -| Property | Value | -| -------------- | ----------------------------- | -| **Format** | Standard 16:9 | -| **Dimensions** | 1280 × 720 px | -| **viewBox** | `0 0 1280 720` | -| **Page Margins** | Left/Right 40px, Top 0px, Bottom 35px | -| **Safe Area** | x: 40-1240, y: 70-665 | - ---- - -## III. Page Structure - -### General Layout - -| Area | Position/Height | Description | -| -------------- | --------------- | -------------------------------------- | -| **Header** | y=0, h=70px | Dark blue background + red left bar + page title | -| **Key Message Bar** | y=70, h=50px | Core message/summary area (light blue-gray background) | -| **Content Area** | y=135, h=515px | Main content area | -| **Footer** | y=665, h=55px | Data source, section name, page number | - -### Decorative Elements - -- **Left Red Bar**: Red (`#CC0000`), width 6px, used for header and card decoration -- **Blue Border**: Accent blue (`#0066CC`), used for card borders -- **Decorative Divider**: Blue (`#0066CC`), paired with decorative dots - ---- - -## IV. Page Types - -### 1. Cover Page (01_cover.svg) - -- White background -- Dark blue top bar + red left vertical bar decoration -- Top-right Logo placeholder area -- Centered main title + subtitle -- Decorative divider line (blue + dots) -- Presenter info area (name, advisor, institution) -- Bottom gray info area (date) - -### 2. Table of Contents Page (02_toc.svg) - -- White background -- Standard header (dark blue + red vertical bar) -- Card-style TOC item layout (2 columns) -- Light blue-gray background cards + left colored vertical bar -- Optional items use dashed borders - -### 3. Chapter Page (02_chapter.svg) - -- Dark blue full-screen background (`#003366`) -- Right-side geometric decorations -- Left red vertical bar decoration -- Large semi-transparent background number -- Prominent white chapter title -- Light blue-gray chapter description -- Red decorative horizontal line - -### 4. Content Page (03_content.svg) - -- White background -- Standard header (dark blue + red vertical bar) -- Key message bar (light blue-gray background + blue left vertical bar) -- Flexible content area -- Footer: data source, section name, page number - -### 5. Ending Page (04_ending.svg) - -- White background -- Dark blue top bar -- Centered thank-you message -- Tagline -- Decorative divider line -- Contact info card (gray background) -- Bottom gray area (copyright, page number) - ---- - -## V. SVG Page Roster - -| File | Role | Description | -|------|------|-------------| -| `01_cover.svg` | cover | Title slide; project name, presenter, date | -| `02_chapter.svg` | chapter | Chapter divider page (large number + chapter title) | -| `02_toc.svg` | toc | Table of contents listing major sections | -| `03_content.svg` | content | Main content page; body of the deck | -| `04_ending.svg` | ending | Closing/thank-you page | - -## VI. Layout Patterns - -| Pattern | Use Cases | -| ------------------ | ------------------------------ | -| **Single Column Centered** | Cover, ending, key points | -| **Two-Column Cards** | Table of contents | -| **Left-Right Split (5:5)** | Comparison display | -| **Left-Right Split (4:6)** | Image-text mixed layout | -| **Card Grid** | Research content list | -| **Timeline** | Research progress | -| **Table** | Data comparison, experiment results | - ---- - -## VII. Spacing Guidelines - -| Element | Value | -| ------------------ | ------ | -| Card gap | 20px | -| Content block gap | 24px | -| Card padding | 20px | -| Card border radius | 8px | -| Icon-to-text gap | 12px | - ---- - -## VIII. Placeholder Specification - -Templates use `{{PLACEHOLDER}}` format placeholders. Common placeholders: - -| Placeholder | Description | -| ------------------ | ------------------ | -| `{{TITLE}}` | Thesis/project main title | -| `{{SUBTITLE}}` | Subtitle | -| `{{AUTHOR}}` | Presenter name | -| `{{ADVISOR}}` | Advisor | -| `{{INSTITUTION}}` | University/institution | -| `{{DATE}}` | Defense date | -| `{{PAGE_TITLE}}` | Page title | -| `{{SECTION_NUM}}` | Section number | -| `{{CHAPTER_NUM}}` | Chapter number (large) | -| `{{CHAPTER_TITLE}}`| Chapter title | -| `{{CHAPTER_DESC}}` | Chapter description | -| `{{KEY_MESSAGE}}` | Key message | -| `{{PAGE_NUM}}` | Page number | -| `{{SOURCE}}` | Data source | -| `{{SECTION_NAME}}` | Section name (footer) | -| `{{TOC_ITEM_N_TITLE}}` | TOC item title (N=1..n) | -| `{{TOC_ITEM_N_DESC}}` | TOC item description (N=1..n) | -| `{{THANK_YOU}}` | Thank-you message | -| `{{ENDING_SUBTITLE}}` | Ending subtitle/tagline | -| `{{CONTACT_INFO}}` | Contact information | -| `{{EMAIL}}` | Email address | -| `{{COPYRIGHT}}` | Copyright info | -| `{{LOGO}}` | Logo text | - ---- - -## IX. Component Specifications - -### 1. Tag - -```xml - - -内容详解 - - - -核心目标 -``` - -### 2. Flow Arrow - -```xml - - - -``` - -### 3. Data Highlight Box - -```xml - - -30% -关键指标 -``` - ---- - -## X. Usage Instructions - -1. Copy the template to the project directory -2. Select the appropriate page template based on defense content needs -3. Use placeholders to mark content that needs replacement -4. Ensure presenter info and advisor info are complete -5. Generate the final SVG through the Executor role diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/01_cover.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/01_cover.svg deleted file mode 100644 index b1c79d48..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/01_cover.svg +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - {{TITLE}} - - - {{SUBTITLE}} - - - - 1 - - - 2 - - - 3 - - - 4 - - - 5 - - - - 智能运维 - - - 数字员工 - - - 自动化测试 - - - 故障诊断 - - - 开放共享 - - - - - - {{AUTHOR}} - {{DATE}} - - - - - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/02_chapter.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/02_chapter.svg deleted file mode 100644 index ce4bbae6..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/02_chapter.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - {{CHAPTER_NUM}} - - - {{CHAPTER_NUM}} - - - {{CHAPTER_TITLE}} - - - - - - - {{CHAPTER_DESC}} - - - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/02_toc.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/02_toc.svg deleted file mode 100644 index 11cc8708..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/02_toc.svg +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - 目 录 - CONTENTS - - - - - 1 - - {{TOC_ITEM_1_TITLE}} - - - - 2 - - {{TOC_ITEM_2_TITLE}} - - - - 3 - - {{TOC_ITEM_3_TITLE}} - - - - 4 - - {{TOC_ITEM_4_TITLE}} - - - - 5 - - {{TOC_ITEM_5_TITLE}} - - - - {{TOC_SUMMARY}} - - - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/03_content.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/03_content.svg deleted file mode 100644 index e5270a2a..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/03_content.svg +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - {{PAGE_TITLE}} - - - - - - {{CONTENT_AREA}} - - - - - - - {{SECTION_NAME}} - - - {{SOURCE}} - - - - {{PAGE_NUM}} - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/04_ending.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/04_ending.svg deleted file mode 100644 index 8c0c96d0..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/04_ending.svg +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - {{THANK_YOU}} - - - {{ENDING_SUBTITLE}} - - - - - - {{CONTACT_INFO}} - - - {{COPYRIGHT}} - - - - - - - - 1 - - - 2 - - - 3 - - - 4 - - - - 能力封装 - - - 跨域拉通 - - - 知识沉淀 - - - 开放共享 - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/design_spec.md deleted file mode 100644 index a45a90d2..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/design_spec.md +++ /dev/null @@ -1,302 +0,0 @@ ---- -layout_id: ai_ops -kind: layout -native_structure_mode: template -summary: Telecom AI operations architecture, IT system overviews, digital transformation proposals, smart infrastructure reports. -canvas_format: ppt169 -page_count: 6 -page_types: [cover, toc, chapter, content, ending, reference_style] ---- - -# ai_ops - Enterprise Digital Intelligence Design Specification - -> Suitable for telecom operator AI operations architecture, digital transformation proposals, smart infrastructure reports, IT system overview diagrams, and other high-information-density scenarios. - -> **Style Reference**: See `reference_style.svg` (Telecom Operator AI Operations Architecture Overview), which demonstrates the core visual language of this template. - ---- - -## I. Template Overview - -| Property | Description | -| ------------------ | ------------------------------------------------------------------------------ | -| **Template Name** | ai_ops (Enterprise Digital Intelligence) | -| **Use Cases** | Telecom AI operations architecture, IT system overviews, digital transformation proposals, smart infrastructure reports | -| **Design Tone** | Information-dense, structured, modular zoning, telecom/enterprise style | -| **Theme Mode** | Light theme (white background + red-blue dual-color accents + warm gray panels) | -| **Info Density** | High density — a single page can accommodate 6-10 information modules, matching telecom reporting conventions | - ---- - -## II. Canvas Specification - -| Property | Value | -| ------------------ | -------------------------------- | -| **Format** | Standard 16:9 | -| **Dimensions** | 1280 × 720 px | -| **viewBox** | `0 0 1280 720` | -| **Page Margins** | Left/right 30-50px, top 20px, bottom 40px | -| **Content Safe Area** | x: 30-1250, y: 80-680 | -| **Title Area** | y: 20-80 | -| **Grid Baseline** | 20px (high-density layouts require a finer grid) | - -> **Note**: Margins are narrower than standard templates (30px vs 60px) to accommodate the high-information-density reporting style common in telecom presentations. - ---- - -## III. Core Design Principles - -### Telecom High-Density Information Style - -This template emulates the visual language of telecom technical reports. The core characteristics are "**modular zoning + high information density + red-blue dual-color hierarchy**". - -1. **Left Red Vertical Bar**: A red rectangle (10×40px) before titles serves as a visual anchor — the most essential title identifier throughout the template. -2. **Number Badges**: Red square badges (30×30px with white numbers) identify key initiatives/capability numbers (e.g., numbers 1-5 in "Five Key Initiatives"). -3. **Dashed Zone Frames**: `stroke-dasharray="5 5"` dashed rectangles group content modules, creating a structured, modular visual effect — a common "zone frame" in telecom reports. -4. **Blue Label Bars**: `#2E75B6` blue-filled rectangles (full-width or fixed-width) serve as scenario/category headers carrying scenario names. -5. **Warm Gray Overview Panels**: Panels with `#FDF3EB` background + `#F8CBAD` border carry overviews, summaries, and open platform entries. -6. **Metric Card Groups**: White cards with `#F2F2F2` borders, closely arranged to display KPI metrics; values highlighted in `#C00000` red. -7. **Light Blue Sub-modules**: `#5B9BD5` filled small rectangular cards displaying specific feature items (e.g., "AI One-Click Troubleshooting Assistant"). -8. **Gray Capability Base Cards**: Cards with `#E7E6E6` / `#F2F2F2` background for displaying foundational capabilities/platform components. - -### Advanced Features - -1. **Triangle Decorations**: The top area may use light semi-transparent triangles (`fill-opacity="0.3"`) as visual guides. -2. **Star/Icon Accents**: Simple polygon stars near key achievements enhance visual impact. -3. **Multi-level Nested Zones**: Outer dashed frame > inner label area > specific feature cards, forming a three-layer visual hierarchy. -4. **Compact Line Spacing**: Module spacing compressed to 10-20px to maximize information capacity. - ---- - -## IV. Page Structure - -### General Layout - -| Area | Position/Height | Description | -| ------------------ | ---------------- | ---------------------------------------------------- | -| **Title Area** | y=20-80 | Red vertical bar + title text + optional subtitle overview bar | -| **Overview Bar** | y=80-140 | Full-width `#F2F2F2` background bar carrying the page's core summary | -| **Content Area** | y=140-670 | Main content area (densely packed multi-module layout) | -| **Footer** | y=680-720 | Red narrow bar with page number + chapter name + source citation | - -### Navigation Bar Design - -- **Title Vertical Bar**: Red rectangle `#C00000`, 10×40px, positioned left of the title text -- **Title Text**: 10px from the vertical bar, 36px font size, `#C00000` or `#000000` -- **Overview Bar**: Full-width light gray rectangle (h=60px), centered 16px body text carrying the page overview/introduction - -### Decorative Elements - -- **Number Badges**: 30×30px red squares + white numbers (centered) -- **Blue Labels**: Fixed-width blue rectangles + white text (e.g., "Fault Boundary Identification") -- **Dashed Zone Frames**: `stroke="#C00000"` or `stroke="#E7E6E6"`, `stroke-dasharray="5 5"` -- **Warm Gray Panels**: `fill="#FDF3EB"` + `stroke="#F8CBAD"` + `stroke-width="2"` -- **Light Blue Feature Cards**: `fill="#5B9BD5"` rectangles + white text - ---- - -## V. Page Types - -### 1. Cover Page (01_cover.svg) - -- **Background**: White `#FFFFFF` -- **Left Decoration**: Full-height red-blue dual-color vertical bar (red upper half + blue lower half), width 60px -- **Title Area**: Centered large title `{{TITLE}}` (red), with subtitle `{{SUBTITLE}}` inside a light gray overview bar below -- **Middle Decoration**: Number badges (1-5) + blue scenario labels showcasing core capabilities/scenarios -- **Bottom Info**: Speaker `{{AUTHOR}}` + date `{{DATE}}` -- **Bottom Decoration**: Warm gray narrow bar + blue full-width bottom bar - -### 2. Chapter Page (02_chapter.svg) - -- **Background**: White `#FFFFFF` -- **Left/Right Decoration**: Left red vertical bar + right blue vertical bar (echoing the cover dual-color scheme) -- **Center**: Red number badge (80×80px large) `{{CHAPTER_NUM}}` + watermark number (160px light gray) -- **Title**: Centered `{{CHAPTER_TITLE}}` (48px Bold) -- **Decorative Line**: Red-blue dual lines (thick red line + thin blue line) -- **Description**: `{{CHAPTER_DESC}}` in gray text - -### 3. Content Page (03_content.svg) - -- **Top**: 4px red top bar + white title bar (80px height) -- **Title Identifier**: Red vertical bar (8×40px) + 32px Bold title `{{PAGE_TITLE}}` -- **Content Area**: Dashed frame (`stroke-dasharray="5 5"`) marking content area `{{CONTENT_AREA}}` -- **Footer**: Light gray bottom bar, left red vertical bar + chapter name `{{SECTION_NAME}}`, right red square page number `{{PAGE_NUM}}` -- **Source Citation**: Footer centered `{{SOURCE}}` -- **TOC**: Use canonical indexed placeholders such as `{{TOC_ITEM_1_TITLE}}` - -### 4. Ending Page (04_ending.svg) - -- **Layout**: Mirrors the cover — left red-blue dual-color vertical bar, bottom blue bar -- **Central Panel**: Warm gray panel (`#FDF3EB` + `#F8CBAD` border) carrying the thank-you message -- **Content**: `{{THANK_YOU}}` (red 64px Bold) + `{{ENDING_SUBTITLE}}` (blue 22px) -- **Contact Info**: `{{CONTACT_INFO}}` + `{{COPYRIGHT}}` -- **Bottom Decoration**: Number badges + blue labels, echoing the cover - ---- - -## VI. SVG Page Roster - -| File | Role | Description | -|------|------|-------------| -| `01_cover.svg` | cover | Title slide; project name, presenter, date | -| `02_chapter.svg` | chapter | Chapter divider page (large number + chapter title) | -| `02_toc.svg` | toc | Table of contents listing major sections | -| `03_content.svg` | content | Main content page; body of the deck | -| `04_ending.svg` | ending | Closing/thank-you page | -| `reference_style.svg` | reference_style | Style reference card (developer aid; not used in normal decks) | - -## VII. Layout Patterns - -| Pattern | Applicable Scenarios | -| ------------------------------ | ------------------------------------------------- | -| **Architecture Overview** | AI operations overview, system architecture panorama | -| **Metrics Dashboard** | KPI display, performance reports, data dashboards | -| **Multi-Module Zoning** | Capability lists, scenario matrices, domain displays | -| **Process/Timeline** | Implementation roadmap, deployment plan, evolution path | -| **Top-Bottom Split** | Objectives+results (top), scenarios+capabilities (bottom) | -| **Left-Right Split (3:7)** | Left navigation labels + right content area | -| **Card Matrix (2x3/3x3)** | Capability modules, team assignments, project lists | -| **Table** | Metric comparisons, progress tracking | - -> **Recommended**: Telecom reports commonly use the "**Architecture Overview**" pattern — a single page presenting the complete architecture from objectives → results → scenarios → orchestration → foundational capabilities, unfolding top to bottom. - ---- - -## VIII. Common Components - -### Title Vertical Bar Decoration - -```xml - - -Page Title -``` - -### Number Badge - -```xml - - -1 -``` - -### Blue Scenario Label - -```xml - - -Fault Boundary Identification -``` - -### Metric Card - -```xml - - -Fault tickets reduced by30% -``` - -### Dashed Zone Frame - -```xml - - -``` - -### Warm Gray Overview Bar - -```xml - - -Overview text content... -``` - -### Warm Gray Panel - -```xml - - -``` - -### Light Blue Feature Card - -```xml - - -AI One-Click Troubleshooting Assistant -``` - -### Gray Capability Base Card - -```xml - - -Core Network -``` - ---- - -## IX. Spacing Specification - -| Element | Value | -| ------------------------------ | --------- | -| Page left/right margins | 30-50px | -| Page top/bottom margins | 20-40px | -| Title area height | 60px | -| Overview bar height | 60px | -| Title to overview bar spacing | 0px | -| Overview bar to content spacing | 10-20px | -| Module spacing | 10-20px | -| Card spacing | 10px | -| Card inner padding | 15-20px | -| Badge to label spacing | 5-10px | -| Footer height | 40px | - -> **Compact Principle**: The telecom style pursues maximum information per page; spacing is generally 30-50% smaller than standard templates. - ---- - -## X. Placeholder Specification - -The template uses `{{PLACEHOLDER}}` format placeholders: - -| Placeholder | Description | Applicable Template | -| ------------------- | ------------------------ | ------------------- | -| `{{TITLE}}` | Main title | Cover | -| `{{SUBTITLE}}` | Subtitle/overview | Cover | -| `{{AUTHOR}}` | Speaker/organization | Cover | -| `{{DATE}}` | Date | Cover | -| `{{CHAPTER_NUM}}` | Chapter number | Chapter page | -| `{{CHAPTER_TITLE}}` | Chapter title | Chapter page | -| `{{CHAPTER_DESC}}` | Chapter description | Chapter page | -| `{{PAGE_TITLE}}` | Page title | Content page | -| `{{CONTENT_AREA}}` | Content area identifier | Content page | -| `{{SECTION_NAME}}` | Section name (footer) | Content page | -| `{{SOURCE}}` | Data source (footer) | Content page | -| `{{PAGE_NUM}}` | Page number | Content/ending page | -| `{{THANK_YOU}}` | Thank-you message | Ending page | -| `{{ENDING_SUBTITLE}}` | Slogan/tagline | Ending page | -| `{{CONTACT_INFO}}` | Contact information | Ending page | -| `{{COPYRIGHT}}` | Copyright | Ending page | - ---- - -## XI. Usage Notes - -1. Copy this template directory to the project `templates/` directory -2. Review `reference_style.svg` to understand the core visual style -3. Select appropriate page templates based on content needs -4. Mark content to be replaced using placeholders -5. Generate final SVG through the Executor role -6. For high-information-density pages, refer to the multi-module zoning layout in `reference_style.svg` - ---- - -## XII. Design Highlights - -- **Telecom DNA**: Derived from real telecom AI operations architecture reports, naturally suited for telecom/enterprise presentation styles -- **High Information Density**: A single page can accommodate a complete architecture view (objectives → results → scenarios → orchestration → foundational capabilities) -- **Red-Blue Dual-Color Hierarchy**: Red = core/emphasis/objectives, Blue = scenarios/modules/capabilities — clear visual hierarchy -- **Number Badge System**: Red square numbers throughout create a "N Key Initiatives" visual narrative -- **Three-Level Nested Zoning**: Dashed outer frame → category labels → feature cards for structured expression of complex architectures -- **Metric Card Groups**: Compactly arranged KPI metrics with red-highlighted values for instant readability diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/reference_style.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/reference_style.svg deleted file mode 100644 index 93535386..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/ai_ops/templates/reference_style.svg +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - - 1 公司运维AI建设总体视图 - - - - - 聚焦用户故障压降,提升优化一键诊断能力,实现降本提质;深入系统架构具备一键故障定位;借助大数据核心网实现网络效能提升;通过能 - 力封装、跨域拉通、知识沉淀、智能编排、开放共享等五大举措,深化AI大模型应用,重塑故障诊断处置流程,做深做实1-5-10 - - - - - - - - 以故障双压降,快速定位故障问题为目标 - - - 成效 - - - 故障工单压降30% - - - IT订单自愈69w - - - 自动化测试覆盖80% - - - 系统监控覆盖100% - - - 监控指标4000+ - - - CMDB纳管7000+ - - - - - 节省运维成本 - 150万 - - - - 应用 - 场景 - - - 故障申告、故障定界定段 - - - RPA数字员工 - - - IT自动化运维 - - - 系统故障快速定位诊断 - - - - 4 - 智能体 - 编排 - - - - 持续迭代用户一键诊断智能体能力;引入RPA,针对固化场景实现RPA数字员工;建设系统故障诊断处置Agent - - - - 网络:AI一键排障助手 - - IT:AI一键查询助手 - - - - NB工单自动化处理 - - IT订单自愈 - - IT自动化测试 - - - - 自动化巡检 - - AI隐患排查助手 - - AI系统诊断助手 - - - 开放 - - 5 - - - 统一监控运维平台 - - 一站服务中台 - - 物联网IT - - 集同昆仑平台 - - B客户推广 - - - 基础 - 能力 - - - - 1 - 梳理3大能力底座,做好场景清单化 - - - 核心网 - - 物联网IT - - 物联网平台 - - - - 2 - 利用数字员工实现日常固化场景自动化 - - - 场景设计 - - 机器人 - - 知识库 - - - - 3 - 实现系统IPS三层监控全覆盖 - - - CMDB - - 日志 - - 调用链 - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/01_cover.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/01_cover.svg deleted file mode 100644 index 80f11dcf..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/01_cover.svg +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{TITLE}} - - - - - {{SUBTITLE}} - - - - - - - - 汇报人:{{PRESENTER}} - - - - - {{ORGANIZATION}} - - - - - {{DATE}} - - - - - - - - - {{ORG_SHORT}} - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/02_chapter.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/02_chapter.svg deleted file mode 100644 index fba20096..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/02_chapter.svg +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0{{CHAPTER_NUM}} - - - - - 0{{CHAPTER_NUM}} - - - - - - - - - {{CHAPTER_TITLE}} - - - - - {{CHAPTER_SUBTITLE}} - - - - - - - - {{ORGANIZATION}} - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/02_toc.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/02_toc.svg deleted file mode 100644 index 2e242f8a..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/02_toc.svg +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 目 录 - - - CONTENTS - - - - - - - - - - - 01 - - - {{TOC_ITEM_1_TITLE}} - {{TOC_ITEM_1_DESC}} - - - - - - 02 - - - {{TOC_ITEM_2_TITLE}} - {{TOC_ITEM_2_DESC}} - - - - - - 03 - - - {{TOC_ITEM_3_TITLE}} - {{TOC_ITEM_3_DESC}} - - - - - - 04 - - - {{TOC_ITEM_4_TITLE}} - {{TOC_ITEM_4_DESC}} - - - - - - 05 - - - {{TOC_ITEM_5_TITLE}} - {{TOC_ITEM_5_DESC}} - - - - - - - - - - - {{PAGE_NUM}} - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/03_content.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/03_content.svg deleted file mode 100644 index a6f55240..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/03_content.svg +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{CHAPTER_NUM}} - - - {{PAGE_TITLE}} - - - {{ORG_SHORT}} - - - - - - - - - - {{CONTENT_AREA}} - - - (由 Executor 根据实际内容自由布局) - - - - - - - - - - - - - - {{PAGE_NUM}} - - - {{ORG_SHORT}} - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/04_ending.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/04_ending.svg deleted file mode 100644 index 569b8f3a..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/04_ending.svg +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{THANK_YOU}} - - - - - {{THANK_YOU_EN}} - - - - - - - - - - 欢迎批评指正 - - - - - {{ORGANIZATION}} - - - - - {{CONTACT_INFO}} - - - - - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/design_spec.md deleted file mode 100644 index 69ddcfd2..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_blue/templates/design_spec.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -layout_id: government_blue -kind: layout -native_structure_mode: template -summary: Key project briefings, Five-Year Plan presentations, work summaries, investment promotion, policy interpretation. -canvas_format: ppt169 -page_count: 5 -page_types: [cover, toc, chapter, content, ending] ---- - -# Government Blue Style Template - Design Specification - -> Suitable for government agency briefings, key project presentations, planning proposals, investment promotion, and similar scenarios across all levels of government. - ---- - -## I. Template Overview - -| Property | Description | -| -------------- | ------------------------------------------------------------ | -| **Template Name** | government_blue (Government Blue Template) | -| **Use Cases** | Key project briefings, Five-Year Plan presentations, work summaries, investment promotion, policy interpretation | -| **Design Tone** | Grand, tech-forward, modern, professional government style | -| **Theme Mode** | Light theme (white background + blue gradient accents) | - ---- - -## II. Canvas Specification - -| Property | Value | -| -------------- | ----------------------------- | -| **Format** | Standard 16:9 | -| **Dimensions** | 1280 × 720 px | -| **viewBox** | `0 0 1280 720` | -| **Page Margins** | Left/Right 60px, Top 80px, Bottom 40px | -| **Safe Area** | x: 60-1220, y: 80-680 | - ---- - -## III. Page Structure - -### General Layout - -| Area | Position/Height | Description | -| ---------- | --------------- | -------------------------------------- | -| **Top** | y=0, h=6px | Blue gradient bar (bright blue → deep blue), full width | -| **Title Bar** | y=30, h=50px | Section number block + title text + top-right logo | -| **Content Area** | y=100, h=560px | Main content area | -| **Footer** | y=680, h=40px | Page number, organization name, bottom decoration line | - -### Navigation Bar Design - -- **Top Decoration Line**: Blue gradient (`#00B4D8` → `#0050B3`), height 6px, full width -- **Bottom Decoration Line**: Deep blue (`#0050B3`), height 4px, y=716 -- **Title Bar** (y=30): - - Section number block: Deep blue square (50×50px), white number centered - - Title text: 20px from number block, 28px font size, `#1A1A1A` - - Top-right logo: Fixed at x=1107, dimensions 113×50px - ---- - -## IV. Page Types - -### 1. Cover Page (01_cover.svg) - -- Deep blue gradient background + tech grid texture -- Left-side bright blue accent bar -- Main title + subtitle (white) -- Presenter/Organization info -- Bottom date area -- Geometric decorative circles - -### 2. Table of Contents (02_toc.svg) - -- Light blue gradient background -- Left-side decorative trapezoid + gradient vertical bar -- Supports up to 5 chapters -- Circular numbering + connector line design -- Floating card effect (simulated with solid colors) - -### 3. Chapter Page (02_chapter.svg) - -- Deep blue gradient background -- Radial glow decoration -- Large chapter number (semi-transparent + stroke effect) -- Chapter title + English subtitle -- Bright blue accent bar - -### 4. Content Page (03_content.svg) - -- Light gradient background -- Gradient number block -- Dashed divider lines -- Flexible content area -- Supports multiple layout modes - -### 5. Ending Page (04_ending.svg) - -- Deep blue gradient background -- Wave curve decoration -- Centered thank-you message (Chinese and English) -- Bright blue divider line -- Contact information - ---- - -## V. SVG Page Roster - -| File | Role | Description | -|------|------|-------------| -| `01_cover.svg` | cover | Title slide; project name, presenter, date | -| `02_chapter.svg` | chapter | Chapter divider page (large number + chapter title) | -| `02_toc.svg` | toc | Table of contents listing major sections | -| `03_content.svg` | content | Main content page; body of the deck | -| `04_ending.svg` | ending | Closing/thank-you page | - -## VI. Layout Modes - -| Mode | Use Cases | -| ------------------ | ------------------------------ | -| **Single Column Centered** | Cover, closing, key points | -| **Two Columns (5:5)** | Comparative display | -| **Two Columns (4:6)** | Image-text mixed layout | -| **Top-Bottom Split** | Process descriptions, policy lists | -| **Three-Column Cards** | Project lists, data display | -| **Matrix Grid** | Category display | -| **Table** | Data comparison, specification lists | - ---- - -## VII. Spacing Guidelines - -| Element | Value | -| ---------------- | ------ | -| Card spacing | 24px | -| Content block spacing | 32px | -| Card padding | 24px | -| Card border radius | 8px | -| Icon-to-text gap | 12px | - ---- - -## VIII. Placeholder Specification - -Templates use `{{PLACEHOLDER}}` format placeholders. Common placeholders: - -| Placeholder | Description | -| ------------------ | ------------------ | -| `{{TITLE}}` | Main title | -| `{{SUBTITLE}}` | Subtitle | -| `{{AUTHOR}}` | Organization name (Chinese) | -| `{{AUTHOR_EN}}` | Organization name (English) | -| `{{PRESENTER}}` | Presenter | -| `{{PAGE_TITLE}}` | Page title | -| `{{CHAPTER_NUM}}` | Chapter number | -| `{{PAGE_NUM}}` | Page number | -| `{{DATE}}` | Date | -| `{{ORGANIZATION}}` | Full organization name | -| `{{ORG_SHORT}}` | Abbreviated organization name | -| `{{CONTACT_INFO}}` | Contact information | -| `{{TOC_ITEM_N_TITLE}}` | TOC item title | -| `{{TOC_ITEM_N_DESC}}` | TOC item description | -| `{{LOGO_HEADER}}` | Header logo filename | - ---- - -## IX. Usage Instructions - -1. Copy the template to the project directory -2. Replace logo files in the images directory (if applicable) -3. Select the appropriate page template based on content requirements -4. Mark content to be replaced using placeholders -5. Generate the final SVG through the Executor role - ---- - -## X. Design Highlights - -- **Tech Gradient**: Bright-to-deep blue gradient reflects a modern tech aesthetic -- **Geometric Decorative Elements**: Circles and grids add a tech atmosphere -- **Wave Curves**: Dynamic decoration on the ending page -- **Floating Card Effect**: Modern design for the table of contents page -- **Clear Visual Hierarchy**: Ensures efficient information delivery diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/01_cover.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/01_cover.svg deleted file mode 100644 index 04e31365..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/01_cover.svg +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{TITLE}} - - - - - {{SUBTITLE}} - - - - - - - - {{AUTHOR}} - - - - - {{AUTHOR_EN}} - - - - - {{DATE}} - - - - - - {{ORGANIZATION}} - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/02_chapter.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/02_chapter.svg deleted file mode 100644 index 81b945da..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/02_chapter.svg +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0{{CHAPTER_NUM}} - - - - - - - - {{CHAPTER_TITLE}} - - - - - {{CHAPTER_SUBTITLE}} - - - - - - - {{ORGANIZATION}} - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/02_toc.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/02_toc.svg deleted file mode 100644 index dca695ab..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/02_toc.svg +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - 目 录 - CONTENTS - - - - - - - - - 01 - {{TOC_ITEM_1_TITLE}} - {{TOC_ITEM_1_DESC}} - - - - - - 02 - {{TOC_ITEM_2_TITLE}} - {{TOC_ITEM_2_DESC}} - - - - - - 03 - {{TOC_ITEM_3_TITLE}} - {{TOC_ITEM_3_DESC}} - - - - - - 04 - {{TOC_ITEM_4_TITLE}} - {{TOC_ITEM_4_DESC}} - - - - - - 05 - {{TOC_ITEM_5_TITLE}} - {{TOC_ITEM_5_DESC}} - - - - - - - - {{STAT_NUMBER_1}} - {{STAT_LABEL_1}} - - - - {{STAT_NUMBER_2}} - {{STAT_LABEL_2}} - - - - - - {{PAGE_NUM}} - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/03_content.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/03_content.svg deleted file mode 100644 index f4eec87a..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/03_content.svg +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - {{CHAPTER_NUM}} - - - {{PAGE_TITLE}} - - - {{ORG_SHORT}} - - - - - - - {{CONTENT_AREA}} - - - (由 Executor 根据实际内容自由布局) - - - - - - - - - - - - - - - {{PAGE_NUM}} - - - {{ORG_SHORT}} - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/04_ending.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/04_ending.svg deleted file mode 100644 index 7fb9f883..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/04_ending.svg +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{THANK_YOU}} - - - - - {{THANK_YOU_EN}} - - - - - - - - {{AUTHOR}} - - - - - {{AUTHOR_EN}} - - - - - {{CONTACT_INFO}} - - - - - - {{ENDING_SUBTITLE}} - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/design_spec.md deleted file mode 100644 index a7da6407..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/government_red/templates/design_spec.md +++ /dev/null @@ -1,176 +0,0 @@ ---- -layout_id: government_red -kind: layout -native_structure_mode: template -summary: Government briefings, policy interpretation, work summaries, project introductions, investment promotion. -canvas_format: ppt169 -page_count: 5 -page_types: [cover, toc, chapter, content, ending] ---- - -# Government Red Style Template - Design Specification - -> Suitable for government agency briefings, policy presentations, work summaries, project introductions, and similar scenarios across all levels of government. - ---- - -## I. Template Overview - -| Property | Description | -| -------------- | ------------------------------------------------------------ | -| **Template Name** | government_red (Government Red Template) | -| **Use Cases** | Government briefings, policy interpretation, work summaries, project introductions, investment promotion | -| **Design Tone** | Authoritative, dignified, professional, modern government style | -| **Theme Mode** | Light theme (white background + government red/blue accents) | - ---- - -## II. Canvas Specification - -| Property | Value | -| -------------- | ----------------------------- | -| **Format** | Standard 16:9 | -| **Dimensions** | 1280 × 720 px | -| **viewBox** | `0 0 1280 720` | -| **Page Margins** | Left/Right 60px, Top 80px, Bottom 40px | -| **Safe Area** | x: 60-1220, y: 80-680 | - ---- - -## III. Page Structure - -### General Layout - -| Area | Position/Height | Description | -| ---------- | --------------- | -------------------------------------- | -| **Top** | y=0, h=6px | Dual-color gradient bar (red + blue), full width | -| **Title Bar** | y=30, h=50px | Section number block + title text + top-right logo | -| **Content Area** | y=100, h=560px | Main content area | -| **Footer** | y=680, h=40px | Page number, organization name, bottom decoration line | - -### Navigation Bar Design - -- **Top Decoration Line**: Dual-color gradient (`#8B0000` → `#003366`), height 6px, full width -- **Bottom Decoration Line**: Government red (`#8B0000`), height 4px, y=716 -- **Title Bar** (y=30): - - Section number block: Government red square (50×50px), white number centered - - Title text: 20px from number block, 28px font size, `#1A1A1A` - - Top-right logo: Fixed at x=1107, dimensions 113×50px - ---- - -## IV. Page Types - -### 1. Cover Page (01_cover.svg) - -- Dark gradient background (primarily government blue) -- Top gold decoration line -- Main title + subtitle (centered, white) -- Organization name -- Bottom date area - -### 2. Table of Contents (02_toc.svg) - -- White background + left-side red vertical bar decoration -- Supports up to 5 chapters -- Numbering uses red square blocks + white numbers -- Optional data display area on the right - -### 3. Chapter Page (02_chapter.svg) - -- Deep blue gradient background -- Large chapter number (semi-transparent decoration) -- Chapter title + English subtitle -- Geometric decorative elements - -### 4. Content Page (03_content.svg) - -- White background -- Standard navigation bar (red number block) -- Flexible content area -- Supports multiple layout modes - -### 5. Ending Page (04_ending.svg) - -- Deep blue background -- Centered thank-you message -- Full organization name -- Contact/Address information - ---- - -## V. SVG Page Roster - -| File | Role | Description | -|------|------|-------------| -| `01_cover.svg` | cover | Title slide; project name, presenter, date | -| `02_chapter.svg` | chapter | Chapter divider page (large number + chapter title) | -| `02_toc.svg` | toc | Table of contents listing major sections | -| `03_content.svg` | content | Main content page; body of the deck | -| `04_ending.svg` | ending | Closing/thank-you page | - -## VI. Layout Modes - -| Mode | Use Cases | -| ------------------ | ------------------------------ | -| **Single Column Centered** | Cover, closing, key points | -| **Two Columns (5:5)** | Comparative display | -| **Two Columns (4:6)** | Image-text mixed layout | -| **Top-Bottom Split** | Process descriptions, policy lists | -| **Three-Column Cards** | Project lists, data display | -| **Matrix Grid** | Category display | -| **Table** | Data comparison, specification lists | - ---- - -## VII. Spacing Guidelines - -| Element | Value | -| ---------------- | ------ | -| Card spacing | 24px | -| Content block spacing | 32px | -| Card padding | 24px | -| Card border radius | 8px | -| Icon-to-text gap | 12px | - ---- - -## VIII. Placeholder Specification - -Templates use `{{PLACEHOLDER}}` format placeholders. Common placeholders: - -| Placeholder | Description | -| ------------------ | ------------------ | -| `{{TITLE}}` | Main title | -| `{{SUBTITLE}}` | Subtitle | -| `{{AUTHOR}}` | Organization name (Chinese) | -| `{{AUTHOR_EN}}` | Organization name (English) | -| `{{PAGE_TITLE}}` | Page title | -| `{{CHAPTER_NUM}}` | Chapter number | -| `{{PAGE_NUM}}` | Page number | -| `{{DATE}}` | Date | -| `{{TOC_ITEM_N_TITLE}}` | TOC item title | -| `{{TOC_ITEM_N_DESC}}` | TOC item description | -| `{{THANK_YOU}}` | Thank-you message | -| `{{CONTACT_INFO}}` | Contact information | -| `{{LOGO_HEADER}}` | Header logo filename | -| `{{COVER_BG_IMAGE}}`| Cover background image filename | - ---- - -## IX. Usage Instructions - -1. Copy the template to the project directory -2. Replace logo files in the images directory (if applicable) -3. Select the appropriate page template based on content requirements -4. Mark content to be replaced using placeholders -5. Generate the final SVG through the Executor role - ---- - -## X. Design Highlights - -- **Dual-Color Gradient Top Decoration**: Red-blue gradient reflects a government style -- **Gold Accent Elements**: Adds a sense of dignity -- **Geometric Decorative Patterns**: Modern government aesthetic -- **Clear Visual Hierarchy**: Ensures efficient information delivery diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/layouts_index.json b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/layouts_index.json index 4c56ab59..8ac7827d 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/layouts_index.json +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/layouts_index.json @@ -1,87 +1,29 @@ { - "academic_defense": { - "summary": "Thesis defense, academic presentations, research progress reports, grant applications.", + "presentation_core": { + "summary": "A structure-first presentation layout system combining familiar PowerPoint defaults with advanced editorial, image, and data compositions.", "canvas_format": "ppt169", - "page_count": 5, + "page_count": 20, "page_types": [ - "cover", - "toc", - "chapter", - "content", - "ending" - ] - }, - "ai_ops": { - "summary": "Telecom AI operations architecture, IT system overviews, digital transformation proposals, smart infrastructure reports.", - "canvas_format": "ppt169", - "page_count": 6, - "page_types": [ - "cover", - "toc", - "chapter", - "content", - "ending", - "reference_style" - ] - }, - "government_blue": { - "summary": "Key project briefings, Five-Year Plan presentations, work summaries, investment promotion, policy interpretation.", - "canvas_format": "ppt169", - "page_count": 5, - "page_types": [ - "cover", - "toc", - "chapter", - "content", - "ending" - ] - }, - "government_red": { - "summary": "Government briefings, policy interpretation, work summaries, project introductions, investment promotion.", - "canvas_format": "ppt169", - "page_count": 5, - "page_types": [ - "cover", - "toc", - "chapter", - "content", - "ending" - ] - }, - "medical_university": { - "summary": "Medical academic reports, case discussions, research presentations, hospital work reports, medical education and training.", - "canvas_format": "ppt169", - "page_count": 5, - "page_types": [ - "cover", - "toc", - "chapter", - "content", - "ending" - ] - }, - "pixel_retro": { - "summary": "Tech talks, programming tutorials, game introductions, geek-style showcases.", - "canvas_format": "ppt169", - "page_count": 5, - "page_types": [ - "cover", - "toc", - "chapter", - "content", - "ending" - ] - }, - "psychology_attachment": { - "summary": "Psychotherapy training, academic lectures, counseling case analysis, professional sharing.", - "canvas_format": "ppt169", - "page_count": 5, - "page_types": [ - "cover", - "toc", - "chapter", - "content", - "ending" + "title_slide", + "title_content", + "section_header", + "two_content", + "comparison", + "title_only", + "blank", + "content_caption", + "picture_caption", + "hero_statement", + "editorial_split", + "three_card", + "kpi_dashboard", + "process_timeline", + "data_story", + "title_picture", + "two_picture_caption", + "screenshot_focus", + "chart_insight", + "table_summary" ] } } diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/01_cover.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/01_cover.svg deleted file mode 100644 index ca1c3df5..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/01_cover.svg +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - {{LOGO}} - - - - - - {{TITLE}} - - - - - {{SUBTITLE}} - - - - - - - - - - - - - 汇报人:{{AUTHOR}} - - - - - {{DEPARTMENT}} | 指导老师:{{ADVISOR}} - - - - - {{INSTITUTION}} - - - - - - - - {{DATE}} - - \ No newline at end of file diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/02_chapter.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/02_chapter.svg deleted file mode 100644 index 13913336..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/02_chapter.svg +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - {{CHAPTER_NUM}} - - - - - - - - - {{CHAPTER_TITLE}} - - - - - {{CHAPTER_DESC}} - - - - - - {{INSTITUTION}} - - \ No newline at end of file diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/02_toc.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/02_toc.svg deleted file mode 100644 index a74ab669..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/02_toc.svg +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - 目 录 - - - - - CONTENTS - - - - - {{LOGO}} - - - - - - - - - - 01 - {{TOC_ITEM_1_TITLE}} - {{TOC_ITEM_1_DESC}} - - - - - 02 - {{TOC_ITEM_2_TITLE}} - {{TOC_ITEM_2_DESC}} - - - - - 03 - {{TOC_ITEM_3_TITLE}} - {{TOC_ITEM_3_DESC}} - - - - - 04 - {{TOC_ITEM_4_TITLE}} - {{TOC_ITEM_4_DESC}} - - - - {{TOC_ITEM_5_TITLE}} - - - - {{TOC_ITEM_6_TITLE}} - - - - - - - - - - - {{INSTITUTION}} - - {{PAGE_NUM}} - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/03_content.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/03_content.svg deleted file mode 100644 index fde25a1a..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/03_content.svg +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - {{SECTION_NUM}} {{PAGE_TITLE}} - - - - - - {{LOGO}} - - - - - - - {{KEY_MESSAGE}} - - - - - - - - - - {{CONTENT_AREA}} - - - - - 可用布局:病例展示、检验结果、影像资料、治疗方案、数据图表等 - - - - - 数据卡片 - - - 数据卡片 - - - - - 数据来源:{{SOURCE}} - - - {{SECTION_NAME}} - - - {{PAGE_NUM}} - - \ No newline at end of file diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/04_ending.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/04_ending.svg deleted file mode 100644 index beceadbf..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/04_ending.svg +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - {{LOGO}} - - - - - - {{THANK_YOU}} - - - - - {{ENDING_SUBTITLE}} - - - - - - - - - - - - - - - - {{INSTITUTION}} - - - {{DEPARTMENT}} - - - {{CONTACT_INFO}} - - - - - - - - - - - - - - - - - {{COPYRIGHT}} - - - {{PAGE_NUM}} - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/design_spec.md deleted file mode 100644 index 4b620ae3..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/medical_university/templates/design_spec.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -layout_id: medical_university -kind: layout -native_structure_mode: template -summary: Medical academic reports, case discussions, research presentations, hospital work reports, medical education and training. -canvas_format: ppt169 -page_count: 5 -page_types: [cover, toc, chapter, content, ending] ---- - -# Hospital / Medical University Template (Medical University Style) - Design Specification - -> Suitable for hospitals, medical universities, affiliated hospitals, and medical research institutions for academic reports, case presentations, research results, and related scenarios. - ---- - -## I. Template Overview - -| Property | Description | -| ---------------- | -------------------------------------------------------------------- | -| **Template Name**| medical_university (Hospital / Medical University Template) | -| **Use Cases** | Medical academic reports, case discussions, research presentations, hospital work reports, medical education and training | -| **Design Tone** | Professional, rigorous, life-affirming, tech-forward, trustworthy | -| **Theme Mode** | Light theme (white background + medical blue title bar + life green accents) | -| **Target Institutions** | All types of medical institutions (hospitals, medical universities, affiliated hospitals, medical research institutes) | - ---- - -## II. Canvas Specification - -| Property | Value | -| ------------------ | ---------------------------- | -| **Format** | Standard 16:9 | -| **Dimensions** | 1280 × 720 px | -| **viewBox** | `0 0 1280 720` | -| **Page Margins** | Left/right 40px, top 0px, bottom 35px | -| **Content Safe Area** | x: 40-1240, y: 70-665 | - ---- - -## III. Page Structure - -### General Layout - -| Area | Position/Height | Description | -| ----------------- | ---------------- | -------------------------------------------- | -| **Header** | y=0, h=70px | Medical blue background + orange left vertical bar + page title | -| **Key Message Bar** | y=70, h=50px | Core message/summary area (light blue background) | -| **Content Area** | y=135, h=515px | Main content area | -| **Footer** | y=665, h=55px | Data source, institution name, page number | - -### Decorative Design - -- **Left Orange Vertical Bar**: Emphasis orange (`#FF6B35`), width 6px, used for header and card decoration -- **Medical Blue Border**: Primary blue (`#0066B3`), used for card borders -- **Green Accents**: Accent green (`#00A86B`), used for health/life-related elements -- **Cross/ECG Decorations**: Medical-themed geometric decorative elements - ---- - -## IV. Page Types - -### 1. Cover Page (01_cover.svg) - -- White background -- Medical blue top horizontal bar + orange left vertical bar decoration -- Upper-right logo/emblem placeholder area -- Centered main title + subtitle -- Decorative divider line (blue + green dots) -- Presenter information area (name, department/advisor, institution) -- Bottom gray info area (date) - -### 2. Table of Contents (02_toc.svg) - -- White background -- Standard header (medical blue + orange vertical bar) -- Card-style TOC layout (2 columns) -- Light blue/light green background cards + left colored vertical bar -- Optional items use dashed borders - -### 3. Chapter Page (02_chapter.svg) - -- Deep medical blue full-screen background (`#004080`) -- Right-side geometric decorations (medical theme) -- Left orange vertical bar decoration -- Large semi-transparent background chapter number -- Prominent white chapter title -- Light blue chapter description - -### 4. Content Page (03_content.svg) - -- White background -- Standard header (medical blue + orange vertical bar) -- Key message bar (light blue background + blue left vertical bar) -- Flexible content area -- Footer: data source, institution name, page number - -### 5. Ending Page (04_ending.svg) - -- White background -- Medical blue top horizontal bar -- Centered thank-you message -- Department/contact information -- Institution logo area - ---- - -## V. SVG Page Roster - -| File | Role | Description | -|------|------|-------------| -| `01_cover.svg` | cover | Title slide; project name, presenter, date | -| `02_chapter.svg` | chapter | Chapter divider page (large number + chapter title) | -| `02_toc.svg` | toc | Table of contents listing major sections | -| `03_content.svg` | content | Main content page; body of the deck | -| `04_ending.svg` | ending | Closing/thank-you page | - -## VI. Layout Patterns (Recommended) - -### Common Layouts for Medical Reports - -| Layout Name | Applicable Scenarios | Features | -| --------------------- | -------------------------------- | ------------------------------ | -| **Single Column Center** | Case overview, main conclusions | Highlights key points, clear hierarchy | -| **Dual Column Comparison** | Before/after treatment, plan comparison | Symmetrical, easy to compare | -| **Image-Text Mixed** | Imaging materials, pathology images | Images with text descriptions | -| **Data Cards** | Lab results, vital signs | Multiple metrics side by side | -| **Timeline** | Disease progression, treatment course | Clear chronological order | -| **Flowchart** | Clinical pathways, procedure standards | Clear steps, logical flow | - ---- - -## VII. Spacing Specification - -| Spacing Type | Value | Usage | -| ------------------ | ----- | -------------------------------- | -| **Page Margins** | 40px | Distance from content to page edge | -| **Card Spacing** | 24px | Spacing between cards | -| **Element Spacing** | 16px | Spacing between elements within cards | -| **Line Height** | 1.5 | Body text line height multiplier | -| **Paragraph Spacing** | 20px | Spacing between paragraphs | - ---- - -## VIII. Placeholder Specification - -| Placeholder | Usage | -| ------------------- | ---------------------------- | -| `{{LOGO}}` | Emblem/institution logo | -| `{{TITLE}}` | Main title | -| `{{SUBTITLE}}` | Subtitle | -| `{{AUTHOR}}` | Presenter name | -| `{{DEPARTMENT}}` | Department/school | -| `{{ADVISOR}}` | Thesis advisor | -| `{{INSTITUTION}}` | Institution name | -| `{{DATE}}` | Date | -| `{{CHAPTER_NUM}}` | Chapter number | -| `{{CHAPTER_TITLE}}` | Chapter title | -| `{{CHAPTER_DESC}}` | Chapter description | -| `{{PAGE_TITLE}}` | Page title | -| `{{KEY_MESSAGE}}` | Key message | -| `{{CONTENT_AREA}}` | Content area | -| `{{SOURCE}}` | Data source | -| `{{PAGE_NUM}}` | Page number | -| `{{SECTION_NAME}}` | Section name (footer) | -| `{{TOC_ITEM_N_TITLE}}` | TOC item title (N=1..n) | -| `{{TOC_ITEM_N_DESC}}` | TOC item description (N=1..n) | -| `{{THANK_YOU}}` | Thank-you message | -| `{{ENDING_SUBTITLE}}` | Ending subtitle/tagline | - ---- - -## IX. Usage Notes - -### 1. Copy Template to Project - -```bash -cp templates/layouts/medical_university/* projects//templates/ -``` - -### 2. Logo Placement Guidelines - -- Cover page: Upper-right corner, approx. 160×50px -- Content page: Upper-right within header, approx. 120×35px -- Ending page: Can be enlarged, centered or paired with contact info - ---- - -## X. Medical Content-Specific Components - -### Data Card (Vital Signs) - -```xml - -Temperature -36.5°C -``` - -### Warning Label - -```xml - -Caution -``` - -### Critical Value Label - -```xml - -Critical -``` diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/01_cover.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/01_cover.svg deleted file mode 100644 index 1f1a2e7a..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/01_cover.svg +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{TITLE}} - - - - - {{SUBTITLE}} - - - - - - - - - 💾 SAVE - - - - 🔀 BRANCH - - - - ⏪ REVERT - - - - 🤝 COLLAB - - - - - ▶ PRESS START TO LEARN ◀ - - - - - {{AUTHOR}} - - - - - - - - - - - - - - - {{VERSION}} - - - - - 01/{{TOTAL_PAGES}} - - - - - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/02_chapter.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/02_chapter.svg deleted file mode 100644 index c3c03ed1..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/02_chapter.svg +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{CHAPTER_NUM}} - - - - - - - - CHAPTER - - - - {{CHAPTER_TITLE}} - - - - - {{CHAPTER_TITLE_EN}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - 2 - - - 3 - - - 4 - - - 5 - - - - - - - - {{PAGE_NUM}}/{{TOTAL_PAGES}} - LOADING... - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/02_toc.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/02_toc.svg deleted file mode 100644 index 2049524e..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/02_toc.svg +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - 📍 {{PAGE_TITLE}} - - - {{PAGE_TITLE_EN}} - - - - - - - - - - - - - - 🔴 关键必学 - - - 01 - - {{TOC_ITEM_1_TITLE}} - - - - - - - 🔴 关键必学 - - 02 - {{TOC_ITEM_2_TITLE}} - - - - - - - 🟡 建议了解 - - 03 - {{TOC_ITEM_3_TITLE}} - - - - - - - 🟢 可选内容 - - 04 - {{TOC_ITEM_4_TITLE}} - - - - - - - - - - 📊 学习进度 - - - - - 0% 完成 - - - - - {{STAT_1}} - 关键内容 - - - - {{STAT_2}} - 建议了解 - - - - {{STAT_3}} - 可选内容 - - - - - █ 点击章节开始学习 - - - - - - ▶ START - - - - - - - - - 02/{{TOTAL_PAGES}} - Table of Contents - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/03_content.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/03_content.svg deleted file mode 100644 index 515b70c7..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/03_content.svg +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - {{PAGE_TITLE}} - - - {{PAGE_TITLE_EN}} - - - - - - - - - - - - - {{CONTENT_AREA}} - - - - - - - {{PAGE_NUM}}/{{TOTAL_PAGES}} - {{PAGE_SUBTITLE}} - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/04_ending.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/04_ending.svg deleted file mode 100644 index 7796c713..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/04_ending.svg +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 🎯 {{THANK_YOU}} - - - {{END_SUBTITLE}} - - - - - - - - - - 1 - - {{SUMMARY_1_TITLE}} - - - - {{SUMMARY_1_LINE_1}} - {{SUMMARY_1_LINE_2}} - {{SUMMARY_1_LINE_3}} - - - - 90% - {{SUMMARY_1_STAT}} - - - - - - - 2 - {{SUMMARY_2_TITLE}} - - - - - {{FEATURE_1}} - - - {{FEATURE_2}} - - - {{FEATURE_3}} - - - {{FEATURE_4}} - - - - - - - - 3 - {{SUMMARY_3_TITLE}} - - - - - - {{COMPARE_A}} - - {{COMPARE_B}} - - - {{ROW_1_A}} - - {{ROW_1_B}} - - - {{ROW_2_A}} - - {{ROW_2_B}} - - - {{ROW_3_A}} - - {{ROW_3_B}} - - - - - - - - - - 🎮 {{CTA_TEXT}} - - - - {{CONTACT_INFO}} - - - - - GAME SAVED ✓ - - - - CONTINUE → - - - - - - - - - - - - - - - - - - - {{PAGE_NUM}}/{{TOTAL_PAGES}} - - - - THE END - Thank You! 🎉 - - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/design_spec.md deleted file mode 100644 index 8bd64bc1..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/pixel_retro/templates/design_spec.md +++ /dev/null @@ -1,246 +0,0 @@ ---- -layout_id: pixel_retro -kind: layout -native_structure_mode: template -summary: Tech talks, programming tutorials, game introductions, geek-style showcases. -canvas_format: ppt169 -page_count: 5 -page_types: [cover, toc, chapter, content, ending] ---- - -# Pixel Retro Style Template - Design Specification - -> Suitable for tech talks, programming tutorials, game-related presentations, geek-style content showcases, and similar scenarios. - ---- - -## I. Template Overview - -| Property | Description | -| -------------- | ---------------------------------------------------------- | -| **Template Name** | pixel_retro (Pixel Retro Template) | -| **Use Cases** | Tech talks, programming tutorials, game introductions, geek-style showcases | -| **Design Tone** | Retro gaming, neon cyberpunk, geek tech, 8-bit style | -| **Theme Mode** | Dark theme (deep space black background + neon accents) | - ---- - -## II. Canvas Specification - -| Property | Value | -| -------------- | ----------------------------- | -| **Format** | Standard 16:9 | -| **Dimensions** | 1280 × 720 px | -| **viewBox** | `0 0 1280 720` | -| **Page Margins** | Left/Right 60px, Top 50px, Bottom 40px | -| **Safe Area** | x: 60-1220, y: 50-680 | - ---- - -## III. Page Structure - -### General Layout - -| Area | Position/Height | Description | -| ---------- | --------------- | -------------------------------------- | -| **Top** | y=0, h=4-6px | Neon green decoration line (dual-line effect) | -| **Title Area** | y=50, h=70px | Page title + English subtitle | -| **Content Area** | y=130, h=510px | Main content area | -| **Footer** | y=680, h=40px | Page number, decoration line, progress indicator | - -### Decorative Elements - -- **Top Decoration Line**: Neon green dual lines (main line 4px + auxiliary line 2px) -- **Bottom Decoration Line**: Neon green dual lines (auxiliary line 4px + main line 4px) -- **Pixel Blocks**: Corner decorations with decreasing opacity (100% → 60% → 30%) -- **Scanline Grid**: Optional low-opacity background grid lines - ---- - -## IV. Page Types - -### 1. Cover Page (01_cover.svg) - -- Deep space black background -- Top/bottom neon decoration lines -- Pixel-style console graphic (optional) -- Main title (neon green glow effect) -- Subtitle (moonlight white) -- Function button group (horizontal layout) -- Bottom prompt text (e.g., "PRESS START") - -### 2. Table of Contents (02_toc.svg) - -- Deep space black background -- Standard top decoration -- Chapter list (with importance labels) - - Red: Essential / Must-learn - - Yellow: Recommended - - Green: Optional -- Pixel-style list design - -### 3. Chapter Page (02_chapter.svg) - -- Deep space black background -- Full-screen neon effect -- Large chapter number (glow effect) -- Chapter title + English subtitle -- Pixel-style decorative frame - -### 4. Content Page (03_content.svg) - -- Deep space black background -- Standard top decoration -- Page title (neon green + glow) -- English subtitle (mist gray) -- **Fully open content area** (y=140 to y=670, width 1160px) -- Bottom page number - -> **Design Principle**: The content page template only provides the page frame (title area + footer). The content area is freely designed by the Executor based on actual content. Available layouts include but are not limited to: cards, progress bars, tables, timelines, comparison charts, etc. - -### 5. Ending Page (04_ending.svg) - -- Deep space black background -- Neon glow main title -- Summary card group -- "GAME SAVED" visual effect -- Progress button group - ---- - -## V. SVG Page Roster - -| File | Role | Description | -|------|------|-------------| -| `01_cover.svg` | cover | Title slide; project name, presenter, date | -| `02_chapter.svg` | chapter | Chapter divider page (large number + chapter title) | -| `02_toc.svg` | toc | Table of contents listing major sections | -| `03_content.svg` | content | Main content page; body of the deck | -| `04_ending.svg` | ending | Closing/thank-you page | - -## VI. Layout Modes - -| Mode | Use Cases | -| ------------------ | ------------------------------ | -| **Single Column Centered** | Cover, closing, key points | -| **Two Columns (5:5)** | Comparative display (e.g., Git vs GitHub) | -| **Dual-Column Cards** | Feature lists, trait comparisons | -| **Three-Column Cards** | Key takeaways, project lists | -| **Progress Bar Display** | Data statistics, usage rates | -| **Timeline** | History, processes, workflows | - ---- - -## VII. Spacing Guidelines - -| Element | Value | -| ---------------- | ------ | -| Card spacing | 20-30px | -| Content block spacing | 30px | -| Card padding | 20-24px | -| Card border radius | 0px (blocky feel) or 4px | -| Border width | 2-3px | -| Icon-to-text gap | 12px | - ---- - -## VIII. Visual Effects - -### Pixel Style Characteristics - -- Blocky icons and decorations -- Use block characters such as: full block, dark shade, light shade, upper half, lower half, small black/white squares for decoration -- Progress bars filled with blocks -- Borders use double lines or dotted patterns -- Card corners with pixel decoration blocks - -### Neon Glow Effect - -Apply glow filters to key text/elements: - -```xml - - - - - - - - - - - -Glowing Text -``` - -> **Conditional enhancement**: Glow filters may enrich the retro treatment, but the core pixel composition must remain legible without them. - -### Emoji Usage - -- 🎮 Game/Save -- 💾 Save -- 🔀 Branch/Merge -- 📁 Folder -- 📝 Document -- 🚀 Release -- ⏪ Revert -- 👾 Developer -- 🌐 Network/Cloud -- ✅ Confirm/Success -- 🎯 Target/Key Point -- 🤔 Question/Thinking - ---- - -## IX. Placeholder Specification - -Templates use `{{PLACEHOLDER}}` format placeholders. Common placeholders: - -| Placeholder | Description | -| ------------------ | ------------------ | -| `{{TITLE}}` | Main title | -| `{{SUBTITLE}}` | Subtitle | -| `{{AUTHOR}}` | Author/Organization | -| `{{PAGE_TITLE}}` | Page title | -| `{{PAGE_TITLE_EN}}`| Page title (English) | -| `{{CONTENT_AREA}}` | Flexible content area | -| `{{CHAPTER_NUM}}` | Chapter number | -| `{{PAGE_NUM}}` | Page number | -| `{{TOTAL_PAGES}}` | Total page count | -| `{{VERSION}}` | Version number | -| `{{TOC_ITEM_N_TITLE}}` | TOC item title | -| `{{THANK_YOU}}` | Thank-you message | -| `{{CONTACT_INFO}}` | Primary contact info | - ---- - -## X. Usage Instructions - -1. Copy the template to the project `templates/` directory -2. Select the appropriate page template based on content requirements -3. Mark content to be replaced using placeholders -4. Generate the final SVG through the Executor role -5. Define glow effects using `filter` (within ``) -6. Maintain consistency of the neon color scheme - ---- - -## XI. Color Quick Reference - -``` -Background Layer: - Main background #0D1117 Deep Space Black - Card background #161B22 Starry Night Blue - Borders #30363D Dark Border - -Accent Colors (use in order): - Primary accent #39FF14 Neon Green - Secondary accent #FF2E97 Cyber Pink - Tertiary accent #00D4FF Electric Blue - Quaternary accent #FFD700 Gold Yellow - -Text: - Primary text #E6EDF3 Moonlight White - Secondary text #8B949E Mist Gray - Emphasis text #FFFFFF Pure White -``` diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/01_title_slide.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/01_title_slide.svg new file mode 100644 index 00000000..6f9f81ae --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/01_title_slide.svg @@ -0,0 +1,21 @@ + + + + + + {{TITLE}} + + + {{SUBTITLE}} + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/02_title_content.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/02_title_content.svg new file mode 100644 index 00000000..5d384774 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/02_title_content.svg @@ -0,0 +1,23 @@ + + + + + + + {{PAGE_TITLE}} + + + {{CONTENT_AREA}} + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/03_section_header.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/03_section_header.svg new file mode 100644 index 00000000..a02de8c1 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/03_section_header.svg @@ -0,0 +1,23 @@ + + + + + + + {{CHAPTER_TITLE}} + + + {{CHAPTER_DESC}} + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/04_two_content.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/04_two_content.svg new file mode 100644 index 00000000..c6d47240 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/04_two_content.svg @@ -0,0 +1,29 @@ + + + + + + + {{PAGE_TITLE}} + + + {{LEFT_CONTENT}} + + + {{RIGHT_CONTENT}} + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/05_comparison.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/05_comparison.svg new file mode 100644 index 00000000..dbc46729 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/05_comparison.svg @@ -0,0 +1,43 @@ + + + + + + + + {{PAGE_TITLE}} + + + {{LEFT_TITLE}} + + + {{LEFT_CONTENT}} + + + {{RIGHT_TITLE}} + + + {{RIGHT_CONTENT}} + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/06_title_only.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/06_title_only.svg new file mode 100644 index 00000000..f40a6474 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/06_title_only.svg @@ -0,0 +1,15 @@ + + + + + + {{PAGE_TITLE}} + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/07_blank.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/07_blank.svg new file mode 100644 index 00000000..82f51c31 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/07_blank.svg @@ -0,0 +1,7 @@ + + + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/08_content_caption.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/08_content_caption.svg new file mode 100644 index 00000000..3736a0ba --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/08_content_caption.svg @@ -0,0 +1,29 @@ + + + + + + + {{PAGE_TITLE}} + + + {{CAPTION}} + + + {{CONTENT_AREA}} + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/09_picture_caption.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/09_picture_caption.svg new file mode 100644 index 00000000..1296eefd --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/09_picture_caption.svg @@ -0,0 +1,29 @@ + + + + + + + {{PAGE_TITLE}} + + + {{CAPTION}} + + + + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/10_hero_statement.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/10_hero_statement.svg new file mode 100644 index 00000000..2f84defa --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/10_hero_statement.svg @@ -0,0 +1,23 @@ + + + + + + + {{KEY_MESSAGE}} + + + {{SUBTITLE}} + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/11_editorial_split.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/11_editorial_split.svg new file mode 100644 index 00000000..4945e50d --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/11_editorial_split.svg @@ -0,0 +1,29 @@ + + + + + + + {{PAGE_TITLE}} + + + {{BODY_TEXT}} + + + + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/12_three_card.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/12_three_card.svg new file mode 100644 index 00000000..f43fb121 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/12_three_card.svg @@ -0,0 +1,37 @@ + + + + + + + + {{PAGE_TITLE}} + + + {{CARD_1}} + + + {{CARD_2}} + + + {{CARD_3}} + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/13_kpi_dashboard.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/13_kpi_dashboard.svg new file mode 100644 index 00000000..182ef569 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/13_kpi_dashboard.svg @@ -0,0 +1,53 @@ + + + + + + + + + + {{PAGE_TITLE}} + + + {{KPI_1}} + + + {{KPI_2}} + + + {{KPI_3}} + + + {{KPI_4}} + + + {{CONTENT_AREA}} + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/14_process_timeline.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/14_process_timeline.svg new file mode 100644 index 00000000..262c7ef9 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/14_process_timeline.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + {{PAGE_TITLE}} + + + {{STEP_1}} + + + {{STEP_2}} + + + {{STEP_3}} + + + {{STEP_4}} + + + {{KEY_MESSAGE}} + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/15_data_story.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/15_data_story.svg new file mode 100644 index 00000000..ab567856 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/15_data_story.svg @@ -0,0 +1,37 @@ + + + + + + + + {{PAGE_TITLE}} + + + {{CONTENT_AREA}} + + + {{KEY_MESSAGE}} + + + {{SOURCE}} + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/16_title_picture.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/16_title_picture.svg new file mode 100644 index 00000000..5a46b40e --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/16_title_picture.svg @@ -0,0 +1,24 @@ + + + + + + + {{PAGE_TITLE}} + + + + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/17_two_picture_caption.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/17_two_picture_caption.svg new file mode 100644 index 00000000..6716b7b3 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/17_two_picture_caption.svg @@ -0,0 +1,49 @@ + + + + + + + + + {{PAGE_TITLE}} + + + + + + + + + {{LEFT_CAPTION}} + + + {{RIGHT_CAPTION}} + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/18_screenshot_focus.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/18_screenshot_focus.svg new file mode 100644 index 00000000..c454458a --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/18_screenshot_focus.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + {{PAGE_TITLE}} + + + + + + {{ANNOTATION}} + + + {{SOURCE}} + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/19_chart_insight.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/19_chart_insight.svg new file mode 100644 index 00000000..a8089845 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/19_chart_insight.svg @@ -0,0 +1,60 @@ + + + + + + + {{PAGE_TITLE}} + + + + {"name":"chart_insight","x":88,"y":176,"width":712,"height":408,"type":"column","categories":["Q1","Q2","Q3","Q4"],"series":[{"name":"Actual","values":[42,55,63,78]},{"name":"Plan","values":[48,58,68,74]}],"show_legend":true,"legend_position":"bottom","style":{"colors":["#64748B","#CBD5E1"],"chart_area_fill":"#F4F6F8","plot_area_fill":"#FFFFFF","text_color":"#475569","axis_color":"#CBD5E1","grid_color":"#E2E8F0","font_family":"Arial"}} + + + Actual + + Plan + + + + + + + + + + + + + Q1 + Q2 + Q3 + Q4 + + + + {{KEY_MESSAGE}} + + + {{SOURCE}} + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/20_table_summary.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/20_table_summary.svg new file mode 100644 index 00000000..f0299ca5 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/20_table_summary.svg @@ -0,0 +1,66 @@ + + + + + + + {{PAGE_TITLE}} + + + + {"name":"table_summary","x":88,"y":176,"width":776,"height":408,"strict_grid":true,"column_widths":[3,2,2],"row_heights":[1,1,1,1,1],"style":{"font_family":"Arial","font_size":17,"header_font_size":16,"header_fill":"#E2E8F0","header_text":"#334155","body_fill":"#FFFFFF","body_text":"#475569","band_fill":"#F8FAFC","border_color":"#D6DCE3","border_width":1,"padding":{"left":12,"right":12,"top":6,"bottom":6},"valign":"middle"},"columns":[{"text":"Metric","bold":true},{"text":"Current","align":"r","bold":true},{"text":"Target","align":"r","bold":true}],"rows":[[{"text":"Adoption"},{"text":"68%","align":"r","bold":true},{"text":"80%","align":"r"}],[{"text":"Cycle time"},{"text":"12 d","align":"r","bold":true},{"text":"8 d","align":"r"}],[{"text":"Quality"},{"text":"94%","align":"r","bold":true},{"text":"97%","align":"r"}],[{"text":"Cost index"},{"text":"1.08","align":"r","bold":true},{"text":"1.00","align":"r"}]]} + + + + + + + + + + + + + Metric + Current + Target + Adoption + 68% + 80% + Cycle time + 12 d + 8 d + Quality + 94% + 97% + Cost index + 1.08 + 1.00 + + + + {{KEY_MESSAGE}} + + + {{SOURCE}} + + diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/design_spec.md new file mode 100644 index 00000000..1ee64c31 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/presentation_core/templates/design_spec.md @@ -0,0 +1,110 @@ +--- +layout_id: presentation_core +kind: layout +category: general +summary: A structure-first presentation layout system combining familiar PowerPoint defaults with advanced editorial, image, and data compositions. +keywords: [general, powerpoint, business, editorial, image, data-story] +canvas_format: ppt169 +canvas_width: 1280 +canvas_height: 720 +canvas_viewbox: "0 0 1280 720" +source_canvas_width: 1280 +source_canvas_height: 720 +source_viewbox: "0 0 1280 720" +replication_mode: fidelity +native_structure_mode: structured +page_count: 20 +page_types: + - title_slide + - title_content + - section_header + - two_content + - comparison + - title_only + - blank + - content_caption + - picture_caption + - hero_statement + - editorial_split + - three_card + - kpi_dashboard + - process_timeline + - data_story + - title_picture + - two_picture_caption + - screenshot_focus + - chart_insight + - table_summary +placeholders: + 01_title_slide: ["{{TITLE}}", "{{SUBTITLE}}"] + 02_title_content: ["{{PAGE_TITLE}}", "{{CONTENT_AREA}}"] + 03_section_header: ["{{CHAPTER_TITLE}}", "{{CHAPTER_DESC}}"] + 04_two_content: ["{{PAGE_TITLE}}", "{{LEFT_CONTENT}}", "{{RIGHT_CONTENT}}"] + 05_comparison: ["{{PAGE_TITLE}}", "{{LEFT_TITLE}}", "{{LEFT_CONTENT}}", "{{RIGHT_TITLE}}", "{{RIGHT_CONTENT}}"] + 06_title_only: ["{{PAGE_TITLE}}"] + 07_blank: [] + 08_content_caption: ["{{PAGE_TITLE}}", "{{CONTENT_AREA}}", "{{CAPTION}}"] + 09_picture_caption: ["{{PAGE_TITLE}}", "{{CAPTION}}"] + 10_hero_statement: ["{{KEY_MESSAGE}}", "{{SUBTITLE}}"] + 11_editorial_split: ["{{PAGE_TITLE}}", "{{BODY_TEXT}}"] + 12_three_card: ["{{PAGE_TITLE}}", "{{CARD_1}}", "{{CARD_2}}", "{{CARD_3}}"] + 13_kpi_dashboard: ["{{PAGE_TITLE}}", "{{KPI_1}}", "{{KPI_2}}", "{{KPI_3}}", "{{KPI_4}}", "{{CONTENT_AREA}}"] + 14_process_timeline: ["{{PAGE_TITLE}}", "{{STEP_1}}", "{{STEP_2}}", "{{STEP_3}}", "{{STEP_4}}", "{{KEY_MESSAGE}}"] + 15_data_story: ["{{PAGE_TITLE}}", "{{CONTENT_AREA}}", "{{KEY_MESSAGE}}", "{{SOURCE}}"] + 16_title_picture: ["{{PAGE_TITLE}}"] + 17_two_picture_caption: ["{{PAGE_TITLE}}", "{{LEFT_CAPTION}}", "{{RIGHT_CAPTION}}"] + 18_screenshot_focus: ["{{PAGE_TITLE}}", "{{ANNOTATION}}", "{{SOURCE}}"] + 19_chart_insight: ["{{PAGE_TITLE}}", "{{KEY_MESSAGE}}", "{{SOURCE}}"] + 20_table_summary: ["{{PAGE_TITLE}}", "{{KEY_MESSAGE}}", "{{SOURCE}}"] +--- + +# Presentation Core — Design Specification + +## I. Template Overview + +Presentation Core is a structure-only library for general business, teaching, +project, and reporting decks. Its regular set mirrors the familiar PowerPoint +layout vocabulary; its advanced set adds asymmetric, editorial, image-led, +process, and data-story compositions without introducing industry-specific +content. + +The light neutral preview treatment exists only to expose hierarchy and slot +geometry. Color, typography, logo, voice, and icon treatment remain downstream +identity decisions and are not owned by this layout. + +## IV. Signature Design Elements + +| Element | Template-specific behavior | +|---|---| +| Shared frame | One restrained Master background and a 64 px horizontal safe frame keep the roster visually coherent without imposing brand chrome. | +| Regular vocabulary | Nine familiar PowerPoint layouts preserve the expected title, content, comparison, caption, picture, and blank starting points. | +| Editorial rhythm | Hero, split, card, process, and data layouts alternate breathing and dense structures instead of repeating one card grid. | +| Image system | Picture layouts use explicit native picture regions for one-image, paired-image, captioned-image, and screenshot scenarios. | +| Native data system | Dedicated chart and table layouts use real native object slots plus a concise interpretation rail, while retaining complete SVG fallbacks. | +| Text entry | General body and object slots begin at the upper-left; centered alignment is reserved for KPI values, short process nodes, and focused statements. | +| Neutral framing | Pale panels and hairlines reveal intended zones in the prototype; downstream deck or brand skin controls final paint. | + +## V. Page Roster + +| SVG | Layout key | PowerPoint picker name | Purpose | +|---|---|---|---| +| `01_title_slide.svg` | `title_slide` | Title Slide | Centered title and subtitle cover | +| `02_title_content.svg` | `title_content` | Title and Content | Page title over one flexible content region | +| `03_section_header.svg` | `section_header` | Section Header | Large section title with supporting description | +| `04_two_content.svg` | `two_content` | Two Content | Equal left and right content regions | +| `05_comparison.svg` | `comparison` | Comparison | Paired headings and paired comparison bodies | +| `06_title_only.svg` | `title_only` | Title Only | Title slot with an otherwise open canvas | +| `07_blank.svg` | `blank` | Blank | Zero-slot composition surface | +| `08_content_caption.svg` | `content_caption` | Content with Caption | Main content with a dedicated caption rail | +| `09_picture_caption.svg` | `picture_caption` | Picture with Caption | Native picture region with a caption column | +| `10_hero_statement.svg` | `hero_statement` | Hero Statement | One dominant claim with a short qualifier | +| `11_editorial_split.svg` | `editorial_split` | Editorial Split | Asymmetric body and picture composition | +| `12_three_card.svg` | `three_card` | Three-Card Synthesis | Three parallel synthesis regions | +| `13_kpi_dashboard.svg` | `kpi_dashboard` | KPI Dashboard | Four compact KPI slots over one evidence region | +| `14_process_timeline.svg` | `process_timeline` | Process Timeline | Four ordered steps plus a takeaway rail | +| `15_data_story.svg` | `data_story` | Data Story | Evidence canvas, interpretation rail, and source line | +| `16_title_picture.svg` | `title_picture` | Title and Picture | Page title over one large native picture region | +| `17_two_picture_caption.svg` | `two_picture_caption` | Two Pictures with Captions | Two equal native pictures with independent captions | +| `18_screenshot_focus.svg` | `screenshot_focus` | Screenshot Focus | Screenshot frame with annotation and source rail | +| `19_chart_insight.svg` | `chart_insight` | Chart and Insight | Native chart region with interpretation and source rails | +| `20_table_summary.svg` | `table_summary` | Table and Summary | Native table region with summary and source rails | diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/01_cover.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/01_cover.svg deleted file mode 100644 index 840de924..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/01_cover.svg +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{TITLE}} - - - - - {{SUBTITLE}} - - - - - {{TITLE_EN}} - - - - - - - - - - - "{{QUOTE}}" - - - —— {{QUOTE_AUTHOR}} - - - - - - {{TAG_1}} - - - {{TAG_2}} - - - {{TAG_3}} - - - {{TAG_4}} - - - - 01 - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/02_chapter.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/02_chapter.svg deleted file mode 100644 index b72298ee..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/02_chapter.svg +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - {{CHAPTER_NUM}} - - - - - - CHAPTER {{CHAPTER_NUM}} - - - - - {{CHAPTER_TITLE}} - - - - - {{CHAPTER_EN}} - - - - - - - - - - - "{{QUOTE}}" - - - —— {{QUOTE_AUTHOR}} - - - - - - {{TAG_1}} - - - {{TAG_2}} - - - {{TAG_3}} - - - {{TAG_4}} - - - - {{PAGE_NUM}} - \ No newline at end of file diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/02_toc.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/02_toc.svg deleted file mode 100644 index b22dcc18..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/02_toc.svg +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - - - - - 内容概览 - - - Contents Overview - - - - - - - - - - - - {{TOC_ITEM_1_TITLE}} - {{TOC_ITEM_1_DESC}} - - - - - - - {{TOC_ITEM_2_TITLE}} - {{TOC_ITEM_2_DESC}} - - - - - - - {{TOC_ITEM_3_TITLE}} - {{TOC_ITEM_3_DESC}} - - - - - - - {{TOC_ITEM_4_TITLE}} - {{TOC_ITEM_4_DESC}} - - - - - - - {{TOC_ITEM_5_TITLE}} - {{TOC_ITEM_5_DESC}} - - - - - - - - - - 📎 学习目标 - - - - - - - - - 1 - {{GOAL_1}} - {{GOAL_1_DESC}} - - - - - - 2 - {{GOAL_2}} - {{GOAL_2_DESC}} - - - - - - 3 - {{GOAL_3}} - {{GOAL_3_DESC}} - - - - - - 4 - {{GOAL_4}} - {{GOAL_4_DESC}} - - - - - 02 - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/03_content.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/03_content.svg deleted file mode 100644 index eeaf7770..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/03_content.svg +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - {{PAGE_TITLE}} - - - {{TITLE_EN}} - - - - - - - - - - {{CONTENT_AREA}} - - - - {{PAGE_NUM}} - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/04_ending.svg b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/04_ending.svg deleted file mode 100644 index 761967b5..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/04_ending.svg +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{THANK_YOU}} - - - - - {{ENDING_SUBTITLE}} - - - - - {{THANK_YOU_EN}} - - - - - - - - {{CLOSING_MESSAGE}} - - - - - - - {{CONTACT_INFO}} - - - {{CONTACT_LINE_2}} - - - - - {{COPYRIGHT}} - - diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/design_spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/design_spec.md deleted file mode 100644 index 91df03d7..00000000 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/layouts/psychology_attachment/templates/design_spec.md +++ /dev/null @@ -1,312 +0,0 @@ ---- -layout_id: psychology_attachment -kind: layout -native_structure_mode: template -summary: Psychotherapy training, academic lectures, counseling case analysis, professional sharing. -canvas_format: ppt169 -page_count: 5 -page_types: [cover, toc, chapter, content, ending] ---- - -# Psychology Healing Template (Psychology Attachment Style) - Design Specification - -> Suitable for psychology, psychotherapy, counseling training, and academic sharing in professional settings. - ---- - -## I. Template Overview - -| Property | Description | -| ---------------- | ------------------------------------------------------------ | -| **Template Name**| psychology_attachment (Psychology Healing Template) | -| **Use Cases** | Psychotherapy training, academic lectures, counseling case analysis, professional sharing | -| **Design Tone** | Professional, warm, healing, trustworthy | -| **Theme Mode** | Light theme (cloud white background + blue-green gradient accent + multi-color semantic colors) | - -### Core Visual Metaphor - -The design adopts "**Secure Base**" as the core visual metaphor: - -- **Structural Stability**: Page layout resembles a secure attachment relationship with clear boundaries and predictable patterns -- **Clear Hierarchy**: Information levels mirror the organization of the attachment system — from biological instinct to higher-order reflection -- **Warm Professionalism**: Colors convey both professional authority and healing warmth - ---- - -## II. Canvas Specification - -| Property | Value | -| ------------------ | ------------------------------- | -| **Format** | Standard 16:9 | -| **Dimensions** | 1280 × 720 px | -| **viewBox** | `0 0 1280 720` | -| **Page Margins** | Left/right 40px, top 60px, bottom 40px | -| **Content Safe Area** | x: 40-1240, y: 60-680 | - -### Page Zones - -| Zone | Y-Range | Height | Usage | -| ---------------- | --------- | ------ | -------------------------- | -| Top Title Area | 60-120 | 60px | Page title, chapter labels | -| Main Content | 130-640 | 510px | Core content display | -| Bottom Info Area | 650-680 | 30px | Page number, chapter nav | - ---- - -## III. Page Structure - -### General Layout - -| Area | Position/Height | Description | -| ----------------- | --------------- | ------------------------------------ | -| **Left Accent** | x=0, w=8px | Dominant color vertical bar (content pages) | -| **Top** | y=60-120 | Page title + English subtitle | -| **Divider** | y=125-130 | Decorative divider line | -| **Content Area** | y=130-640 | Main content area (510px height) | -| **Footer** | y=650-700 | Page number, chapter info | - -### Decorative Design - -- **Left Accent Bar**: Dominant color (`#2E5C8E`), width 8px, spanning the full page height -- **Divider Line**: Light gray (`#E5E7EB`), width 1-2px -- **Circle Decorations**: Low-opacity circles for chapter page/cover backgrounds - ---- - -## IV. Page Types - -### 1. Cover Page (01_cover.svg) - -- **Background**: Blue-green gradient (`#1E3A5F` → `#2E5C8E` → `#3D8B7A`) -- **Decoration**: Optional background image (opacity=0.25) -- **Title Area**: Centered, main title 52px + subtitle 28px -- **English Title**: Light gray, 24px -- **Decorative Line**: Warm orange thin line, 200px wide -- **Bottom**: Quote card (semi-transparent background + healing green left border) -- **Tags**: Keyword tags (semi-transparent capsules) -- **Page Number**: Bottom-right, 14px - -### 2. Table of Contents (02_toc.svg) - -- **Background**: Cloud white (`#F8FAFC`) -- **Left Accent**: Dominant color 8px vertical bar -- **Title**: "Contents Overview" -- **Left Side**: Five-chapter list (colored number blocks + title + description) - - Chapter 1: Dominant blue `#2E5C8E` - - Chapter 2: Healing green `#3D8B7A` - - Chapter 3: Warm orange `#E07843` - - Chapter 4: Cool gray-blue `#64748B` - - Chapter 5: Trauma red `#B54545` -- **Right Side**: Learning objectives card -- **Center**: Dashed divider - -### 3. Chapter Page (02_chapter.svg) - -- **Background**: Blue-green gradient -- **Decoration**: Multiple low-opacity concentric circles, diagonal line accents -- **Large Number**: 120px, semi-transparent white, centered -- **Chapter Label**: Capsule shape "CHAPTER X" -- **Title**: 48px white bold -- **Subtitle**: 24px light gray English -- **Decorative Line**: Warm orange thin line, 200px -- **Quote**: Semi-transparent quote card -- **Keywords**: Bottom tag group -- **Page Number**: Bottom-right - -### 4. Content Page (03_content.svg) - -- **Background**: Cloud white -- **Left Accent**: Dominant blue 8px vertical bar -- **Title Area**: Main title 28px + English subtitle 16px -- **Divider**: Decorative line below title -- **Content Area**: Flexible layout (three-column / left-right split / single column) -- **Card Styles**: - - White background + light gray border - - Border radius 12-16px - - Colored top bar / colored left border -- **Bottom Tip**: Light gray background tip bar (optional) -- **Page Number**: Bottom-right - -### 5. Ending Page (04_ending.svg) - -- **Background**: Blue-green gradient -- **Decoration**: Network connection graph (dots + lines) -- **Title**: Main title 56px + subtitle 28px -- **English**: Light gray English title -- **Decorative Line**: Warm orange thin line, 300px -- **Info Area**: Semi-transparent info card -- **Bottom**: Copyright information - ---- - -## V. SVG Page Roster - -| File | Role | Description | -|------|------|-------------| -| `01_cover.svg` | cover | Title slide; project name, presenter, date | -| `02_chapter.svg` | chapter | Chapter divider page (large number + chapter title) | -| `02_toc.svg` | toc | Table of contents listing major sections | -| `03_content.svg` | content | Main content page; body of the deck | -| `04_ending.svg` | ending | Closing/thank-you page | - -## VI. Layout Patterns - -### 7.1 Three-Column Side-by-Side (Comparison/Findings) - -``` -[Card 1: 360px] [Gap: 40px] [Card 2: 360px] [Gap: 40px] [Card 3: 360px] -``` - -- Each card: Colored top bar + icon + number + title + content + bottom tag -- Suitable for: Three findings, three-type comparisons - -### 7.2 Left-Right Split - -``` -[Left Column: 560px] [Gap: 60px] [Right Column: 580px] -``` - -- Left side: Concepts/theory -- Right side: Application/practice -- Suitable for: Concept explanations, therapeutic relationships - -### 7.3 Vertical Stack (Hierarchical Structure) - -``` -┌─────────────────────────────────┐ -│ Top Layer: Metacognition │ -├─────────────────────────────────┤ -│ Representation Layer │ -├─────────────────────────────────┤ -│ Affective Layer │ -├─────────────────────────────────┤ -│ Somatic Layer │ -└─────────────────────────────────┘ -``` - -- Suitable for: Self-development hierarchy, theoretical frameworks - -### 7.4 Attachment Type Quadrant - -| Secure (Green) | Avoidant (Gray-Blue) | -| Anxious-Ambivalent (Orange) | Disorganized (Red) | - -- Each card uses the corresponding attachment type color scheme - ---- - -## VII. Visual Element Specifications - -### 8.1 Card Styles - -```xml - - - - - - - - - - -``` - -### 8.2 Number Blocks - -```xml - -1 -``` - -### 8.3 Tag Styles - -```xml - - -Tag Text -``` - -### 8.4 Quote Cards - -```xml - - - -Quote content -``` - -### 8.5 Divider Lines - -```xml - -``` - ---- - -## VIII. Icon Usage - -Use `tabler-outline` as the stylistic icon library for this template. It matches the professional, warm, low-noise psychology tone and avoids heavy filled symbols. - -### Placeholder Format - -```xml - -``` - -### Common Icon Mappings - -| Concept | Icons | -| -------------------- | ------------------------- | -| Attachment/Bonding | `tabler-outline/heart`, `tabler-outline/link` | -| Secure Base | `tabler-outline/home`, `tabler-outline/shield-check` | -| Mentalization | `tabler-outline/brain`, `tabler-outline/bulb` | -| Affect Regulation | `tabler-outline/activity`, `tabler-outline/adjustments-horizontal` | -| Awareness | `tabler-outline/eye`, `tabler-outline/compass` | -| Trauma | `tabler-outline/alert-triangle`, `tabler-outline/bolt` | -| Repair | `tabler-outline/refresh`, `tabler-outline/tool` | -| Development | `tabler-outline/trending-up`, `tabler-outline/layers-linked` | - ---- - -## IX. Placeholder Specification - -| Placeholder | Usage | -| -------------------- | -------------------- | -| `{{TITLE}}` | Main title | -| `{{SUBTITLE}}` | Subtitle | -| `{{TITLE_EN}}` | English title | -| `{{PAGE_TITLE}}` | Content page title | -| `{{CONTENT_AREA}}` | Flexible content area | -| `{{CHAPTER_NUM}}` | Chapter number | -| `{{CHAPTER_TITLE}}` | Chapter title | -| `{{CHAPTER_EN}}` | Chapter English title | -| `{{QUOTE}}` | Quote content | -| `{{QUOTE_AUTHOR}}` | Quote author | -| `{{PAGE_NUM}}` | Page number | -| `{{COVER_BG_IMAGE}}` | Cover background image path | -| `{{TOC_ITEM_N_TITLE}}` | TOC item title | -| `{{TOC_ITEM_N_DESC}}` | TOC item description | -| `{{THANK_YOU}}` | Thank-you message | -| `{{CONTACT_INFO}}` | Primary contact info | - ---- - -## X. Usage Notes - -### Template Usage Steps - -1. **Copy Template**: Copy template files to the project `templates/` directory -2. **Replace Placeholders**: Replace `{{}}` placeholders with actual content -3. **Adjust Colors**: Fine-tune the color scheme based on the theme -4. **Generate Content**: Use the Executor role to generate specific pages -5. **Post-process**: Run `finalize_svg.py` to complete image embedding - -### Applicable Topics - -- Psychotherapy and counseling -- Attachment theory research -- Developmental psychology -- Clinical case analysis -- Academic training lectures -- Psychology course instruction diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/spec_lock_reference.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/spec_lock_reference.md index ed2a305d..b48b7f0f 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/spec_lock_reference.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/templates/spec_lock_reference.md @@ -37,7 +37,7 @@ > Strategist: fill only colors actually used. Add extra rows as needed; delete unused rows rather than leave as `#......`. > -> **PowerPoint theme roles.** Structured export maps `bg` / `background` / `master_bg` → `lt1`, `secondary_bg` / `bg_secondary` → `lt2`, `text` / `body_text` → `dk1`, `text_secondary` → `dk2`, `primary` → `accent1`, `accent` → `accent2`, `secondary_accent` → `accent3`, and `border` → `accent4`. The first two additional non-black/non-white roles become `accent5` / `accent6`; remaining colors stay fixed. Mapping is usage-aware, so a background HEX is not automatically reused for inverse text. +> **PowerPoint theme roles.** Flat and structured export map `bg` / `background` / `master_bg` → `lt1`, `secondary_bg` / `bg_secondary` → `lt2`, `text` / `body_text` → `dk1`, `text_secondary` → `dk2`, `primary` → `accent1`, `accent` → `accent2`, `secondary_accent` → `accent3`, and `border` → `accent4`. The first two additional non-black/non-white roles become `accent5` / `accent6`; remaining colors stay fixed. Mapping is usage-aware, so a background HEX is not automatically reused for inverse text. > > **`image_rendering` and `image_palette`** — required only when `images` section below contains `ai`-sourced files. Values MUST be valid names from `references/image-renderings/_index.md` and `references/image-palettes/_index.md`, **or** the literal string `custom`. Image_Generator reads these and applies them deck-wide. Omit both rows when the deck has no AI-generated images. > @@ -75,9 +75,9 @@ > > **Size slots are anchors, not a closed menu.** Common slots (`title` / `subtitle` / `annotation`) cover frequent cases. Add role-specific slots (e.g. `cover_title: 88`, `hero_number: 56`, `subheading: 32`, `lead: 30`, `footnote: 16`, `chart_annotation: 16`) for the roles the deck actually uses — common for cover-heavy decks, consulting-style hero numbers, dense pages. **Mandatory — scan `§IX` and declare a slot for every role that recurs across pages, not just the four defaults.** A report / `text`-mode deck almost always recurs a per-page **core-message / lead line** and **page numbers / source credits / footnotes** → declare `lead` and `footnote` for them. `subheading` and `lead` sit between `subtitle` and `body` (their bands overlap `subtitle`) — pick by role, not size — and the core-message `lead` is a **primary** line, **always ≥ `body`**, never smaller. Leaving a recurring lead / footnote undeclared forces the Executor to improvise an unlocked size (and a core line improvised below `body` inverts the hierarchy). **Structural roles (title / body / subtitle / annotation / footnote) render at their locked size on every page — one role, one size, deck-wide.** Intermediate in-band sizes are for special / feature elements only (hero number, display title, one-off emphasis); declare a recurring one as its own slot so it stays consistent too. > -> **Structured Master defaults**: `pptx_structure.mode: structured` requires unitless `title` and `body`. Native export writes `title` into every Master `titleStyle` default and `body` into every `bodyStyle` / `otherStyle` default, changing only `a:defRPr@sz`. Direct page-run sizes and role-specific Layout placeholder prototype sizes remain unchanged. +> **Generated Master defaults**: `pptx_structure.mode: flat` and `mode: structured` require unitless `title` and `body`. Native export writes `title` into every generated Master `titleStyle` default and derives a deterministic nine-level, non-increasing size hierarchy from `body` for `bodyStyle` / `otherStyle`. It changes only each level's `a:defRPr@sz`, preserving indentation, bullets, and paragraph settings. Direct page-run sizes and role-specific structured-Layout placeholder prototype sizes remain unchanged. > -> **⚠️ PPT-safe stack discipline (HARD rule).** Structured export maps `title_family` to the PowerPoint theme major font and `body_family` (or `font_family`) to the theme minor font. Runs whose resolved face matches either role use `+mj-*` / `+mn-*` theme tokens; other role families remain concrete per-run typefaces. Every exported Latin / EA face MUST therefore resolve to cross-platform pre-installed fonts: `"Microsoft YaHei"` / `SimSun` / `Arial` / `"Times New Roman"` / `Consolas`. Stacks that resolve to non-preinstalled typefaces (Inter / Google Fonts / brand typefaces) may be used only when the Design Spec notes the font-install or embedding requirement. +> **⚠️ PPT-safe stack discipline (HARD rule).** Flat and structured export map `title_family` to the PowerPoint theme major font and `body_family` (or `font_family`) to the theme minor font. Runs whose resolved face matches either role use `+mj-*` / `+mn-*` theme tokens; other role families remain concrete per-run typefaces. Every exported Latin / EA face MUST therefore resolve to cross-platform pre-installed fonts: `"Microsoft YaHei"` / `SimSun` / `Arial` / `"Times New Roman"` / `Consolas`. Stacks that resolve to non-preinstalled typefaces (Inter / Google Fonts / brand typefaces) may be used only when the Design Spec notes the font-install or embedding requirement. > > **Stack length discipline.** 3-4 fonts per stack is the sweet spot. Converter only writes the **first** Latin and **first** CJK font into PPTX — everything after is silently dropped. macOS-only families (`Songti SC`, `Menlo`, `Monaco`, `Helvetica`) are auto-mapped to Windows equivalents via `FONT_FALLBACK_WIN` (see `scripts/svg_to_pptx/drawingml/utils.py`); stacking both is redundant. Lead with Windows-preinstalled fonts (`Microsoft YaHei` / `SimSun` / `Arial` / `Georgia` / `Consolas`); keep at most **one** macOS-exclusive family (typically `"PingFang SC"`) as a browser-preview nicety. @@ -125,39 +125,40 @@ > **Missing or empty section** → Executor falls back to `dense` for every page (legacy pre-rhythm behavior). Remove the section only for legacy decks; new decks MUST fill it. ## pptx_structure -- mode: structured +- mode: flat -> One deck-wide native PowerPoint structure policy. New projects always use `structured`; Master/Layout structure exists before the first SVG is drawn. +> One deck-wide native PowerPoint structure policy. Free-design and brand-only routes use `flat`; deck/layout template routes use `structured`. > -> When Step 3 loaded a deck/layout template, add exactly one of: -> ``` -> - template_adherence: adaptive -> - template_adherence: strict -> ``` -> Omit the row for free design and brand-only templates. Both values require one `page_layouts` row per page. Existing legacy template SVGs that lack the current root Master identity, grouped slot/carrier contract, or positive bounds must run [`restore-pptx-structure`](../workflows/restore-pptx-structure.md) before they can be selected. +> `flat` keeps every SVG object Slide-local. Export materializes one clean project-owned Master plus one Blank Layout, maps the current color/typography lock into the theme and Master defaults, removes stock content placeholders and unused built-in Layouts, and retains only the standard date/footer/slide-number capability hooks. In this mode, omit `pptx_masters`, `pptx_layouts`, `page_pptx_layouts`, and `page_layouts`, and do not add root Master/Layout identity, `data-pptx-layer`, or `data-pptx-placeholder*` metadata to generated pages. > -> Template example: +> When Step 3 loaded a deck/layout template, replace the `flat` row above with exactly one of: > ``` > - mode: structured > - template_adherence: adaptive > ``` +> or: +> ``` +> - mode: structured +> - template_adherence: strict +> ``` +> Both values require complete `pptx_masters`, `pptx_layouts`, `page_pptx_layouts`, and `page_layouts` sections. Existing legacy template SVGs that lack the current root Master identity, grouped slot/carrier contract, or positive bounds must run [`restore-pptx-structure`](../workflows/restore-pptx-structure.md) before they can be selected. ## pptx_masters - master-default: Default Master -> One row per Master: `: `. Free design defaults to one Master. Add another only when the design genuinely needs it or the source PPTX carries multiple Masters. Keys are deck-unique and stable. +> Deck/layout template routes only. One row per Master: `: `. Keys are deck-unique and stable. Omit this entire section when `pptx_structure.mode: flat`. ## pptx_layouts -- P01: master-default | cover-hero-split | Cover — Hero Split -- P02: master-default | kpi-band-trio | KPI Band Trio -- P03: master-default | content-two-column | Two Column -- P04: master-default | content-two-column | Two Column +- cover-hero-split: master-default | Cover — Hero Split | template:01_cover +- kpi-band-trio: master-default | KPI Band Trio | P02 +- content-two-column: master-default | Two Column | template:03a_content_abstract +- quote-focus: master-default | Quote Focus | template:04_quote_focus -> Include exactly one row per page before SVG generation. Value format: ` | | `. +> Deck/layout template routes only. This is the unique reusable Layout roster, not a page roster. Value format: ` | | `. A prototype source is either `P` for one generated page carrying that exact Layout contract, or `template:` for an installed `templates/.svg`. Omit this section when `pptx_structure.mode: flat`. > -> The page SVG repeats all three identities on its root through `data-pptx-master`, `data-pptx-master-name`, `data-pptx-layout`, and `data-pptx-layout-name`. A Layout key belongs to exactly one Master and must be globally unique even when two source Masters use the same picker name. +> Every Layout key appears exactly once, belongs to exactly one declared Master, and is globally unique even when two Masters use the same picker name. Every declared Master owns at least one Layout definition. A Layout may remain unused by generated pages; such a Layout must use `template:` so export can register it without manufacturing a published slide. > -> Strategist plans the initial family roster. Executor writes the declared structure while drawing each page. If adaptive template use genuinely changes the reusable framing or slot topology/bounds, create a new Layout key and update this mapping immediately; never silently mutate a reused key. +> The definition prototype repeats its identity through root `data-pptx-master`, `data-pptx-master-name`, `data-pptx-layout`, and `data-pptx-layout-name`. Strategist plans the initial roster. If adaptive use genuinely changes reusable framing or slot topology/bounds, Executor adds a new definition and updates the page assignment immediately; never mutate a reused key silently. > > Reuse one `(master_key, layout_key)` only when its ordered Layout atoms and slot ids/types/indices/bounds/binding modes are identical. Current text, imagery, crop, or Slide-local geometry does not define Layout identity. > @@ -165,18 +166,26 @@ > > A Layout may have zero slots. Do not create an empty `utility` kind or a full-page fake `object` slot; the named Layout and its fixed atoms are sufficient. +## page_pptx_layouts +- P01: cover-hero-split +- P02: kpi-band-trio +- P03: content-two-column +- P04: content-two-column + +> Deck/layout template routes only. Include exactly one row per generated page. The value is one key declared in `pptx_layouts`; Master and picker name come from that unique definition and are not repeated per page. The generated SVG root must match the assigned definition. Omit this section when `pptx_structure.mode: flat`. + ## page_layouts - P01: 01_cover - P03: 02a_chapter - P04: 03a_content_abstract -> For a deck/layout template route, include one entry per page. Key: `P` matching §IX. Value: the template SVG basename without extension. This is the input prototype mapping; `pptx_layouts` is the output mapping and is present at the same time. Strict preserves the prototype Master/Layout/slot contract. Adaptive retains its Master contract and may explicitly assign a new Layout key while authoring. Non-mirror skin follows the project lock. +> For a deck/layout template route, include one entry per page. Key: `P` matching §IX. Value: the template SVG basename without extension. This is the authoring-input prototype mapping; `page_pptx_layouts` is the output page assignment, while `pptx_layouts` defines the unique reusable roster. Strict preserves the prototype Master/Layout/slot contract. Adaptive retains its Master contract and may explicitly define and assign a new Layout key while authoring. Non-mirror skin follows the project lock. > -> **No entry for a page** is valid only when the entire route is free design or brand-only. It is an error in template mode. +> **No entry for a page** is an error in structured template mode. > > **Hard rule**: Use both `page_layouts` and `page_charts` only with a compatible shell. Adaptive mode may start from a neutral content template and finalize a new explicit Layout after design; strict mode must choose an existing compatible Layout or revise the outline. > -> **Whole section omitted** → free design or brand-only route. Template strict/adaptive routes require complete `page_layouts`. A legacy package that cannot satisfy the current structured contract must migrate before use; it never enters a compatibility branch inside normal generation. +> **Whole section omitted** → required for free-design and brand-only `flat` routes. Template strict/adaptive routes require complete `page_layouts`. A legacy package that cannot satisfy the current structured contract must migrate before use; it never enters a compatibility branch inside normal generation. > > **Strategist source**: record each project-page choice in project `design_spec.md §IX Content Outline`, using the copied template package's `templates/design_spec.md §V Page Roster` descriptions as the roster authority. Basenames must match files in `templates/` exactly. A typo is a blocking contract error: stop before drawing and report it; never fall back to free design inside template mode. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-brand.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-brand.md index 7e92864d..cf05b9a6 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-brand.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-brand.md @@ -52,6 +52,8 @@ Identify which of (colors / typography / logo / voice / icon style) the asset di - `[approx]` — visual estimate (PNG/JPG color picking) - `[user]` — supplied via chat fill-in in Step 3 +**Hard rule — brand truth boundary**: Use `fact` only for a literal value extracted from an official asset/manual. Use `user` for values dictated in chat. Values inferred from an existing deck, website appearance, raster sampling, or presentation convention remain `approx`. Keep approximate presentation neutrals minimal; do not invent a semantic info/success/alert palette and lock it as brand identity. + --- ## Step 2B: Verbal spec capture @@ -66,7 +68,7 @@ Whatever the user gives is `[user]`-labelled. Skip Step 3 unless the user explic ## Step 2C: Empty skeleton -Write `templates/brands//templates/design_spec.md` with the full schema, every value as a TODO comment. Tell the user where the file is. No further prompting — the user owns it from here. +Write `templates/brands//templates/design_spec.md` with the full schema, every value as a TODO comment. Tell the user where the file is. Do not register the incomplete skeleton; registration requires concrete identity values. No further prompting — the user owns it from here. --- @@ -80,6 +82,7 @@ For fields not covered by the asset, ask the user in a single bundled message. S | text / bg HEX | only if dark-mode or inverted scheme mentioned | | title / body font | when the asset gave no font reference | | logo usage | when a logo file was provided | +| brand scope | when assets mix a company, product, subsidiary, or campaign identity | | voice & tone | when audience or formality was mentioned | | icon style preference | when icon consistency was mentioned | @@ -100,7 +103,6 @@ mkdir -p "skills/ppt-master/templates/brands//templates" brand_id: kind: brand summary: -keywords: [<3-5 short tags>] primary_color: "#XXXXXX" --- @@ -114,15 +116,16 @@ primary_color: "#XXXXXX" | Brand Name | | | Use Cases |

| | Tone | | +| Sources | | ## II. Color Scheme | Role | HEX | Provenance | |---|---|---| | primary | #XXXXXX | fact \| approx \| user | -| secondary | #XXXXXX | | -| accent | #XXXXXX | | -| text | #XXXXXX | optional, default `#1A1A1A` | -| bg | #XXXXXX | optional, default `#FFFFFF` | +| secondary | #XXXXXX | fact \| approx \| user | +| accent | #XXXXXX | fact \| approx \| user | +| text | #XXXXXX | fact \| approx \| user; optional, default `#1A1A1A` | +| bg | #XXXXXX | fact \| approx \| user; optional, default `#FFFFFF` | ## III. Typography | Role | Family | Weight | @@ -154,6 +157,9 @@ primary_color: "#XXXXXX" - HEX must be `#RRGGBB` - Font names are free strings; not validated against locally installed fonts - §VII is fully optional — list only directories that actually exist +- A company/product family may share one preset when the user explicitly wants that scope. Name the combined scope in §I and identify the owner of every logo/lockup in §IV; never relabel a product mark as the company mark. +- One preset has one default presenting entity. Subsidiary/campaign assets may remain as explicit alternates, but they never silently replace the default identity; create a separate brand workspace when their colors, typography, or voice differ. +- Record official usage or trademark restrictions next to the affected asset. Do not turn an observed public logo into permission to imply affiliation, sponsorship, or endorsement. ### Optional: logo file @@ -169,18 +175,18 @@ No SVG page roster, canvas spec, signature design elements, or preview PPTX. Do --- -## Step 5: Register and hand off +## Step 5: Validate, register, and hand off -Update `templates/brands/brands_index.json` with the new entry (create the file if missing): +Run the registrar in dry-run mode first. It validates the mandatory frontmatter, brand ID, required sections, roster-free scope, `#RRGGBB` colors and primary-color consistency, color provenance, and every referenced `images/` / `icons/` asset: -```json -{ - "": { - "summary": "", - "keywords": [...], - "primary_color": "#XXXXXX" - } -} +```bash +python3 skills/ppt-master/scripts/register_template.py --kind brand --dry-run +``` + +Fix every reported error, then register the same workspace: + +```bash +python3 skills/ppt-master/scripts/register_template.py --kind brand ``` Emit the confirmation card: diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template.md index 9240fd83..05d78b73 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template.md @@ -45,23 +45,23 @@ Both scopes write this contract: ├── templates/ # design_spec.md, template SVGs, templates/icons/ when used ├── images/ # optional; every bitmap; SVG href is ../images/ ├── icons/ # optional; runtime copy of extracted vector assets -└── exports/ # optional; on-demand _template_preview.pptx +└── exports/ # conditional; required package evidence for multi-Master templates ``` -The review PPTX is derived evidence, not a source template asset. Do not create `exports/` unless a review deck is requested. Template application reads `templates/` plus any existing `images/` and `icons/`; it never copies or consumes `exports/`. Library `exports/` directories are Git-ignored. +The review PPTX is derived evidence, not a source template asset. Create `exports/` only when a review deck is requested or the template declares more than one Master; multi-Master templates require the package-level gate in Step 6. Template application reads `templates/` plus any existing `images/` and `icons/`; it never copies or consumes `exports/`. Library `exports/` directories are Git-ignored. For `project`, `target_project` is required and must be an existing project initialized by `project_manager.py init`. Before the first final-output write, run one complete preflight. Apply the same collision checks to a library workspace; the only difference is that its root is under the global kind directory: 1. Resolve `` from the confirmed scope and confirm its required `templates/` destination plus any needed `images/` / `icons/` destinations. 2. Confirm `/templates/` is empty. -3. Resolve every final bitmap and extracted-icon filename, then confirm none would overwrite an existing file in `images/`, `icons/`, or `templates/icons/`. Check the review-PPTX destination only when preview export was requested. +3. Resolve every final bitmap and extracted-icon filename, then confirm none would overwrite an existing file in `images/`, `icons/`, or `templates/icons/`. Check the review-PPTX destination when preview export was requested or a multi-Master template was confirmed. Any failed check aborts before writing `design_spec.md`, SVGs, images, icons, or the review PPTX. Do not merge into a non-empty template source and do not overwrite a name conflict. Temporary Step 1 analysis workspaces remain allowed because they are not final outputs. ## Process Overview ``` -Reference Intake & Analysis -> Basic Norm Extraction -> Fact-Based Brief Proposal -> User Confirmation Gate -> Preflight + Invoke Template_Designer -> Validate Assets -> [Optional Review PPTX] -> [Register Library Index] -> Output +Reference Intake & Analysis -> Basic Norm Extraction -> Fact-Based Brief Proposal -> User Confirmation Gate -> Preflight + Invoke Template_Designer -> Validate Assets -> [Review PPTX: optional for one Master, required for multi-Master] -> [Register Library Index] -> Output ``` The first three steps derive the brief from facts, not guesses. **No final template directory may be created and no template SVG / `design_spec.md` may be written until `[TEMPLATE_BRIEF_CONFIRMED]` is emitted in Step 3.** Reference-analysis intermediates produced by `pptx_template_import.py` (typically under `/tmp/pptx_template_import/`) are explicitly **not** subject to this gate — they are temporary workspaces feeding Step 2. @@ -171,13 +171,13 @@ Interpretation rule (carries forward into Steps 2 and 4): - cleaned complete-page projections are optional composition spot checks for authored modes and verification views for mirror. They are never the lossless restoration source. - screenshots remain useful for judging composition and style, but should not override extracted factual metadata unless the import result is clearly incomplete -**Mirror reachability gate**: compare every `native_structure.json.layouts[*].usedBySlides` -entry with the source Master roster before offering `mirror`. The current -structured template compiler materializes only identities referenced by emitted -SVG prototypes. If any source Layout is unused, or any source Master is not -reachable through a referenced Layout, full-graph mirror is currently -unsupported. Report the exact keys and stop; do not silently omit them or create -a synthetic carrier page. +**Mirror complete-graph gate**: compare every `native_structure.json` Layout +and Master with the layered projection inventory before offering `mirror`. +Every source Layout—including one unused by all source slides—must have a +lossless Layout projection from which a reusable definition SVG can be restored. +Every source Master must own at least one retained Layout. Missing projections +or ambiguous parentage are blocking; unused identities themselves are supported +and must not be dropped. ### Basic norm extraction (mandatory when reference content exists) @@ -264,7 +264,7 @@ Compose a single message that surfaces every Required brief item to the user, ** | Theme mode | Recommended localized mode with English ID, plus available modes such as `light` / `dark` / `mixed` with localized explanations | | Canvas format | Recommended canvas, plus other supported formats from [`canvas-formats.md`](../references/canvas-formats.md) that fit the source aspect ratio or user intent. Always show the concrete pixel size and `viewBox`; do not treat two same-ratio formats such as `ppt169` (`1280x720`) and `banner` (`1920x1080`) as interchangeable. | | Replication mode | Recommended localized mode with English ID, plus all modes available for the current input type; state that `standard` / `fidelity` design a new structure while `mirror` restores the source structure; list unavailable modes with reasons | -| Native structure policy | For `standard` / `fidelity`, state that the designer will author a new Master/Layout/slot system without preserving or distilling source topology. For `mirror`, summarize the exact source Master/Layout/placeholder graph that will be restored one-to-one. | +| Native structure policy | For `standard` / `fidelity`, state that the designer will author a new Master/Layout/slot system without preserving or distilling source topology. Show the planned Master roster; if it contains more than one Master, explain the distinct reusable family owned by each and which Layouts belong to it. Reject one-Master-per-Layout organization and visually/semantically equivalent duplicate Masters. For `mirror`, summarize the exact source Master/Layout/placeholder graph that will be restored one-to-one. | | Visual fidelity for fixed pages | Recommended localized choice with English ID, plus both `literal` / `adapted` options when applicable | | Asset bundling | Recommended included assets, plus excluded candidate assets with a one-line reason when reference assets exist | @@ -281,9 +281,9 @@ Items to surface: | Tone summary | Yes | `[suggested]` from analysis (e.g. `Modern, restrained, data-driven`) | | Theme mode | Yes | A: `[fact]` from `manifest.json` background colors. B: `[fact]` from SVG `fill`. C: `[suggested]` from visual estimate. D: `[decision]` | | Canvas format and dimensions | Yes | A/B: `[fact]` from slide size or SVG `width` / `height` / `viewBox`; show `canvas_format`, `canvas_width`, `canvas_height`, `canvas_viewbox`, and `source_viewbox`. C: `[suggested]` from image aspect ratio. D: `[decision]`, default `ppt169` (`1280x720`, `0 0 1280 720`) | -| Replication mode | Yes | `[decision]` — `standard` always available; `fidelity` is available for A/B; `mirror` is available for A only when every source Master/Layout is reachable from a source slide, and only for B sources with a complete explicit structure contract whose declared identities are all page-referenced. `standard` / `fidelity` author new SVG semantics, while mirror retains one restored prototype per source slide in source order. Reject `fidelity` / `mirror` for C/D. | +| Replication mode | Yes | `[decision]` — `standard` always available; `fidelity` is available for A/B; `mirror` is available for A and for B sources with a complete explicit structure contract. `standard` / `fidelity` author new SVG semantics. Mirror retains one restored prototype per source slide in source order and adds definition-only prototypes for source Layouts unused by those slides. Reject `fidelity` / `mirror` for C/D. | | Native structure facts | Type A and structured Type B | `[fact]` from `native_structure.json` / source SVG contract: master/layout counts, parentage, page assignments, placeholder identities, and multi-master status. Mirror restores these facts; authored modes do not use them as output topology. | -| Mode-specific ownership | Yes | `standard` / `fidelity`: `[decision]` newly authored Master/Layout ownership. `mirror`: `[fact]` source ownership restored without synthesis. Export never infers either contract. | +| Mode-specific ownership | Yes | `standard` / `fidelity`: `[decision]` newly authored Master/Layout ownership, including the reusable-family reason for every additional Master. `mirror`: `[fact]` source ownership restored without synthesis. Every Master must own at least one emitted Layout and every Layout must have at least one emitted prototype; export never infers either contract. | | Visual fidelity for fixed pages | Yes for `standard` / `fidelity` when reference exists; **N/A for `mirror`** (mirror restores the source visual) | `[decision]` — `literal` (closely reproduce reference geometry / decoration / sprite crops within a newly authored structure) or `adapted` (use reference tone/composition but allow design evolution). Different page types may take different settings. | | Basic template norms | Yes when reference exists | `[fact]` / `[suggested]` — layout grammar, image system, density rhythm, page roster semantics, and asset policy extracted in Step 1 | | Reference source | Optional | already known if Step 1 ran | @@ -323,7 +323,7 @@ Skipping this gate — including silently inferring values from the reference so - [ ] Output scope is confirmed; both scopes use the same workspace shape, while `project` includes an explicit initialized target-project path - [ ] The canvas format is fixed before SVG generation - [ ] Replication mode is consistent with the input type (`fidelity` allowed for A/B; `mirror` allowed for A and structured B only; both forbidden for C/D) -- [ ] Before offering `mirror`, every source Layout has at least one source-slide reference and every source Master is reachable through those Layouts; otherwise the exact unsupported identities were reported and mirror was not selected +- [ ] Before offering `mirror`, the source graph and supported geometry are complete; every source Layout absent from the source-slide roster is planned as a definition-only prototype, and any genuinely missing/unsupported facts were reported - [ ] Basic template norms from prior content have been surfaced and accepted, or explicitly marked N/A when no reference exists - [ ] Mode-specific ownership policy is explicit: `standard` / `fidelity` author a new structure without source-topology distillation; `mirror` restores source ownership one-to-one - [ ] For `library`, metadata is complete enough to register into the relevant index; for `project`, the same portable template metadata is complete and no global registration is planned @@ -384,13 +384,24 @@ The role interprets the package according to replication mode: **Hard rule — mode-specific authorship**: `standard` and `fidelity` author new SVG documents and compact canonical metadata. `mirror` restores the lossless source contract and may only normalize transport details required by the current compiler. Mirror never performs commonality extraction, semantic synthesis, merge/split, promotion/demotion, renaming, or re-parenting. +**Hard rule — multi-Master package boundary**: More than one Master is valid only when `mirror` restores the source graph or an authored template intentionally defines distinct reusable design families. `standard` / `fidelity` must not create one Master per Layout or duplicate equivalent Masters merely for organization. Every declared Master must own at least one emitted Layout, and every declared Layout must be selected by at least one prototype SVG so the complete graph can be compiled and verified. + +| Package concern | Requirement | +|---|---| +| Theme ownership | Every registered Slide Master receives its own Theme part. Two Masters must never resolve to the same `ppt/theme/themeN.xml`. Theme cloning is exporter-owned; do not author or bundle Theme XML in the template workspace. | +| Creation identity | Any generated `p14:creationId` on Slides, Layouts, or Masters is a valid unsigned 32-bit value and unique across those parts. Cloned structural parts always receive fresh values. | +| Numeric registration | Master and Layout registration IDs are valid and unique in their owning lists; Layout numeric IDs are unique across the complete package, including across different Masters. | +| Relationship graph | The presentation registers the exact Master and Slide rosters; each Master registers exactly its owned Layouts; each Layout targets exactly one declared Master; each Slide targets exactly its declared Layout. | + +SVG authors own the semantic roster, parentage, picker names, direct atoms, and slots. The exporter owns OOXML part cloning, Theme isolation, relationship registration, and package identity. Do not encode package repair workarounds in individual template SVGs. + Do not package `native_structure.json` or `source_template.pptx` as template inputs. In `standard` / `fidelity`, author Master/Layout direct atoms and bounded slot groups deliberately from the intended reusable behavior. In `mirror`, use the lossless layered and flat SVGs plus inheritance/native facts to preserve source ownership. Recursively expand fixed Master/Layout group wrappers only because the structured contract requires direct atoms; preserve transforms, styles, paint order, and appearance, and never flatten or regroup by semantic judgment. `design_spec.md §V` records the newly authored roster for `standard` / `fidelity`. For `mirror`, add the `Source Restoration Map` required by [template-designer.md](../references/template-designer.md), with one row per source slide and its preserved Master/Layout assignment. Do not add a synthesis-decision table. **Native-shape metadata boundary**: The lightweight authoring projection removes opaque payload only from model context; it never becomes the restoration source. `standard` / `fidelity` use compact canonical shapes and assets rather than copied source payload. `mirror` reuses only native metadata already supported by the converter on unchanged Slide-local/slot objects. Fixed layers are normalized to direct atoms; unsupported or edited objects keep the current SVG fallback and are reported rather than silently replaced by stale metadata. -Downstream, both template-adherence choices use `pptx_structure.mode: structured`. `page_layouts` selects one complete input prototype per page, while `pptx_masters` and `pptx_layouts` declare the output mapping before the first SVG. Strict preserves the selected prototype contract. Adaptive keeps its Master and may explicitly create a new Layout key/name while authoring the page that needs it. A mirror-created package does not force a future generated deck to keep the source page count or order. +Downstream, both template-adherence choices use `pptx_structure.mode: structured`. `page_layouts` selects one complete authoring prototype per page, `pptx_masters` / `pptx_layouts` declare unique reusable definitions, and `page_pptx_layouts` assigns generated pages. Strict preserves the selected prototype contract. Adaptive keeps its Master and may explicitly create and assign a new Layout key/name while authoring the page that needs it. A retained Layout may remain unassigned while still registering through its definition SVG. A mirror-created package does not force a future generated deck to keep the source page count or order. **Apply the visual-fidelity decision from Step 3 to authored modes**: in `standard` / `fidelity`, pages marked `literal` reproduce the selected reference geometry and decoration while still using a newly designed structure; pages marked `adapted` may evolve the composition. Mirror restores every supported source visual and does not use this authored-page distinction. @@ -401,6 +412,7 @@ Downstream, both template-adherence choices use `pptx_structure.mode: structured 1. **Restores one output SVG per source page** in `/templates/`. Use lightweight projections for inspection, but materialize from the matching lossless source and native structure facts. Preserve source Master/Layout keys and picker names, Layout parentage, slide assignment, placeholder type/index/bounds, ownership, paint order, and supported native metadata. Mechanical namespace, root-declaration, asset-path, and fixed-layer group normalization is allowed only when source ownership and appearance remain unchanged. - Type A restoration source: `/svg/`, `/svg-flat/`, `svg/inheritance.json`, and `native_structure.json` - Type B restoration source: the complete explicit source SVG contract; `authoring-svg/` remains inspection-only + - For every source Layout unused by all source slides, additionally restore one definition-only SVG named `layout_.svg` from its lossless Master/Layout projections. It carries the exact root identity, fixed atoms, and placeholder contract but is not a generated page assignment. Use source placeholder prompts/carriers; do not invent business content. This definition SVG lets downstream export register the Layout and any otherwise-unused parent Master without retaining an internal carrier slide. 2. **Renames each file** using the source-order-first convention `_.svg`, where `` is the source-order index zero-padded to 3 digits and `` is typically `cover` / `toc` / `chapter` / `content` / `ending` (fall back to `content` when the type cannot be confidently classified). Examples: `001_cover.svg`, `002_toc.svg`, `003_content.svg`, ..., `050_ending.svg`. - Type A: derive `` from `manifest.json.pageTypeCandidates` - Type B: derive `` from the source filename when it follows the PPT Master convention (`01_cover.svg` → `cover`, `03a_content_two_col.svg` → `content`); otherwise infer from page content or fall back to `content` @@ -418,9 +430,22 @@ Mirror mode does not simplify the visual target or synthesize layer ownership. T 1. `design_spec.md` — **personality only**. Required sections: Template Overview, Color Scheme, Signature Design Elements, Page Roster (matching the actual SVG files on disk). Skip Typography / Assets / Placeholder Overrides when they would just restate defaults. Declare portable brief frontmatter; `register_template.py` consumes it only in library scope. **Do not** restate generic SVG constraints, layout pattern libraries, font-size ratio bands, the canonical placeholder table, or content methodology — those are sourced from `shared-standards.md` / `design_spec_reference.md` / `strategist.md` and are already in the downstream reader's context. Full scope rule and skeleton: [template-designer.md §1](../references/template-designer.md#1-must-generate-design_specmd). 2. Page roster — see [Page Roster](../references/template-designer.md#page-roster) for `standard` / `fidelity` / `mirror` mode rosters, variant naming, and TOC handling 3. Placeholder vocabulary — pages should adopt the conventional names (`{{TITLE}}`, `{{CONTENT_AREA}}`, ...) when they fit. Full reference: [Placeholder Reference](../references/template-designer.md#4-placeholder-reference-canonical-convention-overridable-per-template). When a template style legitimately needs different vocabulary (consulting → `{{KEY_MESSAGE}}`, branded cover → `{{BRAND_LOGO}}`), declare a `placeholders:` block in `design_spec.md` frontmatter so the registrar and quality checker treat it as the template's authoritative contract. **Avoid** one-off indexed families such as `{{CHAPTER_01_TITLE}}` — use the indexed TOC pattern instead. - - `{{...}}` placeholders are the authoring vocabulary used to generate final slide content. Each emitted SVG also carries the native reconstruction contract: root Master/Layout key/name, direct atomic Master/Layout elements, and direct slot `` elements with explicit design-zone bounds plus exactly one compatible carrier. Composite regions use only the explicit `object` + `proxy` downgrade. Minimal structural `data-pptx-role` hints are added only when specialized metadata cannot express required behavior. Both strict and adaptive downstream set `mode: structured` and require complete `page_layouts`, `pptx_masters`, and `pptx_layouts` from planning onward. + - `{{...}}` placeholders are the authoring vocabulary used to generate final slide content. Each emitted SVG also carries the native reconstruction contract: root Master/Layout key/name, direct atomic Master/Layout elements, and direct slot `` elements with explicit design-zone bounds plus exactly one compatible carrier. Composite regions use only the explicit `object` + `proxy` downgrade. Minimal structural `data-pptx-role` hints are added only when specialized metadata cannot express required behavior. Both strict and adaptive downstream set `mode: structured` and require complete `page_layouts`, `page_pptx_layouts`, `pptx_masters`, and `pptx_layouts` from planning onward. 4. Template assets (optional) — both scopes apply the same `templates/` / `images/` / dual-icon routing defined above +**Hard rule — placeholder examples are executable defaults**: In authored +`standard` / `fidelity` templates, a carrier is not a floating review label. It +becomes the prototype Slide placeholder, while +`data-pptx-placeholder-bounds` becomes the reusable Layout frame. + +| Concern | Requirement | +|---|---| +| Full editable frame | `data-pptx-placeholder-bounds` describes the complete intended text, picture, chart, table, or object box. Never derive it from the sample text's glyph bounds or leave it as a one-line tight box. | +| Generic text entry | General `body` and text-carried `object` slots begin at the upper-left, use left paragraph alignment, and wrap inside the full frame. Title/subtitle alignment follows the authored composition. | +| Centered exceptions | Center alignment is reserved for semantically short focal content such as KPI values, short process nodes, hero statements, and compact takeaways. Record a template-wide exception in `design_spec.md §IV` when it is part of the layout grammar. | +| Review Slide binding | `template_preview_pptx.py` sizes each authored Slide carrier to the same complete frame as its registered Layout placeholder. A review deck whose Slide carrier is only the prompt text's tight box fails Step 6. | +| Mirror boundary | `mirror` preserves source Slide carrier geometry exactly; do not normalize it to the Layout frame when the source intentionally overrides that frame. | + --- ## Step 5: Validate Template Assets @@ -449,6 +474,8 @@ python3 skills/ppt-master/scripts/svg_quality_checker.py "/t - validate cross-page Master equality plus same-key Layout atom/slot equality - warn when distinct Layout keys have identical static framing/slot contracts. Resolve this for `standard` / `fidelity`; mirror may retain the distinct source identities and records that fact in its Source Restoration Map +This checker validates the authoring contract, not the compiled OOXML package. Theme ownership, package IDs, and registered part relationships are verified by `template_preview_pptx.py` in Step 6. + **Checklist**: - [ ] `design_spec.md` follows the personality-only skeleton (Overview / Color / Signature / Page Roster); generic constraints (SVG rules, pattern libraries, ratio bands, canonical placeholder table) are NOT restated. The source-derived basic norms are present as template-specific layout / image / density / asset rules, not generic advice. §V Page Roster lists every emitted page @@ -462,22 +489,24 @@ python3 skills/ppt-master/scripts/svg_quality_checker.py "/t - [ ] `design_spec.md` frontmatter declares `native_structure_mode: structured`; no `native_structure.json` or `source_template.pptx` is packaged - [ ] Every SVG root declares Master/Layout key and picker names; Master/Layout visuals are direct atoms, never ``, and obey the explicit paint-order contract. Structural `data-pptx-role` is used only when specialized metadata cannot express required package/page-number/animation behavior - [ ] Every slot is a direct `` with explicit design-zone bounds and exactly one compatible direct carrier, or an explicit composite `object` proxy; zero-slot Layouts remain valid +- [ ] For `standard` / `fidelity`, every placeholder bound is the complete editable box rather than the current marker text's tight bounds; general body/object carriers begin at the upper-left and only intentional short focal roles remain centered - [ ] `standard` / `fidelity` output SVGs and their Master/Layout/slot contracts were newly authored without preserving or distilling source topology +- [ ] Every additional authored Master represents a distinct reusable design family, not one Layout or an equivalent duplicate; every declared Master owns at least one emitted Layout and every declared Layout has at least one emitted prototype - [ ] Mirror output preserves source slide order, Master/Layout identity and parentage, placeholder facts, and ownership; fixed-layer group expansion is mechanical and pixel-equivalent, and the Source Restoration Map lists every source slide -- [ ] Mirror preflight proved that the source graph has no unused Layout or unreachable Master that the one-prototype-per-source-slide roster would silently omit +- [ ] Mirror preflight covered the complete source graph; each unused Layout has one `layout_.svg` definition prototype and each otherwise-unused Master is retained through at least one such Layout - [ ] For `standard` / `fidelity`, no duplicate-Layout-contract warning remains; mirror may keep equivalent source Layout identities when the restoration map explains them - [ ] Lightweight projections were used only for inspection. Mirror materialized from lossless sources, reused only converter-supported metadata on unchanged Slide-local/slot objects, and kept fixed Master/Layout visuals as direct atoms - [ ] If any SVG references an extracted vector `data-icon`, the corresponding SVG asset exists under `/templates/icons/` and the identical runtime copy exists under `/icons/`; do not add a separate illustration embedding script - [ ] For `fidelity` mode: every sprite-sheet asset retains its nested `` crop wrapper; no image whose file aspect differs from its on-page aspect was flattened to a bare `` -- [ ] For `mirror` mode: file count equals source page count (type A: `/*_*.svg` matches the lossless `/svg-flat/slide_*.svg` count; type B: matches the source SVG count); filenames follow the `_.svg` convention; **no new `{{...}}` authoring placeholders were inserted into restored SVGs**; §V Page Roster in `design_spec.md` lists every emitted file with a one-line description of what the page contains and what content slot it suits +- [ ] For `mirror` mode: source-page SVG count equals source page count, while additional files are exactly the required `layout_.svg` definitions for unused source Layouts; source-page filenames follow the `_.svg` convention; **no new `{{...}}` authoring placeholders were inserted into restored source-page SVGs**; §V Page Roster lists every emitted file and marks definition-only prototypes explicitly -This step is a **hard gate**. Do not generate an optional review PPTX, register, or hand the workspace to the main pipeline until validation passes. +This step is a **hard gate**. Do not generate a review PPTX, register, or hand the workspace to the main pipeline until validation passes. A one-Master template may skip Step 6 when no review was requested; a multi-Master template must continue to Step 6 and may not register or complete before that package gate passes. --- -## Step 6: Optional Template Review PPTX +## Step 6: Template Review PPTX and Multi-Master Package Gate -**Trigger**: Run only when the user requests a PowerPoint review file. Otherwise skip directly to Step 7 and do not create `exports/`. +**Trigger**: Run when the user requests a PowerPoint review file **or** when the validated SVG roster declares more than one unique Master key. A multi-Master template requires this step even when no review artifact was requested. A one-Master template may skip directly to Step 7 when the user did not request a review file. Export the complete SVG roster, one prototype per slide, from the workspace root: @@ -498,9 +527,15 @@ python3 skills/ppt-master/scripts/template_preview_pptx.py " - [ ] Review PPTX exists under `/exports/` - [ ] PPTX slide count equals the template SVG roster count - [ ] Package read-back reports the expected Master and Layout counts +- [ ] The presentation registers the exact Master and Slide rosters; every Master registers exactly its owned Layouts; every Layout and Slide relationship resolves to its declared parent +- [ ] Every registered Master targets a distinct Theme part; shared Theme ownership across structured Masters is a hard failure +- [ ] Generated `p14:creationId` values are valid and unique across Slides, Layouts, and Masters; Master/Layout numeric registration IDs are valid and unique in their required scopes +- [ ] For `standard` / `fidelity`, every carrier-bound placeholder on each review Slide has exactly the same type, effective index, and full frame as its registered Layout placeholder; `template_preview_pptx.py` verifies this automatically +- [ ] For `mirror`, source Slide-local placeholder geometry remains unchanged even when it differs from the Layout default frame - [ ] The user can open one file and review every template page in deterministic filename order +- [ ] When Microsoft PowerPoint is available for acceptance testing, the file opens without a repair prompt and every emitted Layout appears under its intended Master. When PowerPoint is unavailable, report package read-back as the verified evidence and do not claim a PowerPoint-open result -If this optional step is run, every validation item becomes a hard gate for the review artifact. Fix the owning SVG/spec/asset before reporting the preview as verified. Failure of an unrequested preview does not block a workspace that already passed Step 5. +`template_preview_pptx.py` automatically enforces the deterministic package checks above during read-back. Every applicable validation item is a hard gate for the review artifact. Fix the owning SVG/spec/asset or exporter defect before reporting the preview as verified. For a multi-Master template, any Step 6 failure blocks registration and completion; for a one-Master template, failure of an unrequested preview does not block a workspace that already passed Step 5. --- @@ -510,7 +545,7 @@ Branch on the confirmed output scope: | Scope | Action | |---|---| -| `library` | Run the registrar below after Step 5 passes and, when requested, Step 6 also passes | +| `library` | Run the registrar below after Step 5 passes and Step 6 also passes whenever it was requested or required by a multi-Master roster | | `project` | Skip the registrar entirely. Do not edit `decks_index.json`, `layouts_index.json`, or any library README; continue to Step 8 with index status `Not registered (project workspace)` | Run the unified registrar with the kind flag; it derives the corresponding index entry from `templates/design_spec.md` (frontmatter when present, prose fallback otherwise) plus the actual `templates/*.svg` file list. The registrar retains read compatibility with old flat library packages; new creation never writes that shape: @@ -599,7 +634,7 @@ Produce one scope-aware, evidence-driven completion card for either location: **Template Source**: `/templates/` **Bitmap Path**: `/images/` ← omit when absent **Runtime Icon Path**: `/icons/` ← omit when absent -**Review PPTX**: `/exports/_template_preview.pptx` ← omit when not requested +**Review PPTX**: `/exports/_template_preview.pptx` ← omit only when a one-Master template was not requested for review **Primary Color**: ← deck only; omit for layout **Index Registration**: Done | Not registered (project workspace) @@ -612,7 +647,7 @@ Produce one scope-aware, evidence-driven completion card for either location: | `templates/02_toc.svg` | Done | | `templates/03_content.svg` | Done | | `templates/04_ending.svg` | Done | -| `exports/_template_preview.pptx` | Verified, when requested | +| `exports/_template_preview.pptx` | Verified, when requested or required for multi-Master | ``` The next main-pipeline Step 3 input is the exact `/` root in either scope. Step 3 resolves its `templates/design_spec.md`, ignores `exports/`, and copies or consumes `templates/` plus any existing `images/` and `icons/` as one unit. A legacy flat package root remains readable, but directory flatness alone is not a legacy Master/Layout condition and does not trigger `restore-pptx-structure`. @@ -636,6 +671,6 @@ The next main-pipeline Step 3 input is the exact `/` root in 2. **Color consistency**: All SVG files must use the same color scheme as `design_spec.md §II Color Scheme` 3. **Placeholder convention**: `{{}}` format only; default names listed in [Placeholder Reference](../references/template-designer.md#4-placeholder-reference-canonical-convention-overridable-per-template). Override per template via `placeholders:` frontmatter when needed. 4. **Discovery requirement**: A library template is discoverable only after `register_template.py` has been run against it (Step 7). A project-scoped workspace intentionally stays out of global discovery and is consumed by its explicit workspace-root path. -5. **Review output**: Generate `exports/_template_preview.pptx` only on request. It is derived local evidence, never a source input during template application, and library exports stay Git-ignored. +5. **Review output**: Generate `exports/_template_preview.pptx` on request and always for a multi-Master template. It is derived local evidence, never a source input during template application, and library exports stay Git-ignored. > **Full role specification**: [template-designer.md](../references/template-designer.md) diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/index.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/index.md index 2dfee775..1cff0045 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/index.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/index.md @@ -21,7 +21,7 @@ Registry for standalone workflows referenced by `SKILL.md` and [`routing.md`](./ | `create-brand` | [`create-brand.md`](./create-brand.md) | Build/extract a reusable brand identity preset | Logo/site/branded deck/PDF or explicit brand setup request | Not a layout/deck template roster | Workflow Step 1 | Complete identity-only workspace under `templates/brands//` | Blocks on brand evidence and validation defined in the workflow | | `resume-execute` | [`resume-execute.md`](./resume-execute.md) | Continue an existing split-mode project | Planning-session artifacts exist | Do not re-run planning | Execution-session entry | SVG generation, post-processing, export | Stops if `design_spec.md` or `spec_lock.md` is missing | | `refine-spec` | [`refine-spec.md`](./refine-spec.md) | User explicitly opts into spec refinement before generation | Strategist confirmation stage completed | Do not enter by default | After Step 4, before Step 5/6 | Revised `design_spec.md` and `spec_lock.md` | Blocks for user review/approval before generation | -| `restore-pptx-structure` | [`restore-pptx-structure.md`](./restore-pptx-structure.md) | Existing project or template uses a legacy/unmapped PowerPoint structure contract | Legacy SVG project/package exists; original PPTX/native facts are preferred when available; legacy-flat packaging alone is not a trigger | Not part of normal new-project generation; exporter never migrates implicitly | Before Step 3 template use, SVG generation, or export | Current structured SVGs plus complete Master/Layout lock mapping | Blocks only when restoration requires an unresolved design decision | +| `restore-pptx-structure` | [`restore-pptx-structure.md`](./restore-pptx-structure.md) | Existing structured project or template uses a legacy/unmapped PowerPoint structure contract | Legacy structured SVG project/package exists; original PPTX/native facts are preferred when available; explicit `mode: flat` free-design/brand-only projects and legacy-flat packaging are not triggers | Not part of normal new-project generation; exporter never migrates implicitly | Before Step 3 template use, structured SVG generation, or structured export | Current structured SVGs plus complete Master/Layout lock mapping | Blocks only when restoration requires an unresolved design decision | | `verify-charts` | [`verify-charts.md`](./verify-charts.md) | Deck contains data charts that require coordinate calibration | SVG pages exist | Not needed for decks without data charts | Between Step 6 and Step 7 | Verified/fixed chart geometry | Blocks on chart coordinate errors | | `customize-animations` | [`customize-animations.md`](./customize-animations.md) | User asks for object-level animation order/effect/timing | Target deck/SVG groups exist | Do not add per-element builds by default | Before or during export configuration | `animations.json` or equivalent validated config | Blocks if target objects cannot be identified | | `native-enhance-pptx` | [`native-enhance-pptx.md`](./native-enhance-pptx.md) | Finished PPTX should keep content/layout stable while adding notes/audio/timing/transitions | Source PPTX exists | No SVG regeneration | Workflow Step 1 | Patched PPTX through OOXML | Blocks on source archive/validation failures | diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/refine-spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/refine-spec.md index 1791d806..b8cabc85 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/refine-spec.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/refine-spec.md @@ -49,7 +49,7 @@ These overlap with what the locked `mode`, visual style, and §6.1 already shape **Keep both files in sync on every change.** Any revision the user approves must land in both `design_spec.md` and `spec_lock.md`; on divergence `spec_lock.md` wins (see [`strategist.md`](../references/strategist.md) §6.2). Iterate as many rounds as the user wants. The loop ends only when the user explicitly approves the spec. -**Re-run the structured-template preflight after structural revisions.** If the user changes `template_adherence`, `page_layouts`, the Master roster, or any page Layout choice, repeat the Strategist preflight in [`strategist.md`](../references/strategist.md) §6.2 before approval and hand-back. Every newly selected prototype must declare root Master/Layout identity, direct atomic Master/Layout visuals, and valid top-level slot groups with positive bounds plus one compatible carrier or explicit composite `object` proxy. A zero-slot Layout is valid. Update `pptx_masters` and the complete per-page `pptx_layouts` mapping in both artifacts immediately. A legacy prototype must run [`restore-pptx-structure`](./restore-pptx-structure.md); do not create a fallback mode inside refinement. +**Re-run the structured-template preflight after structural revisions.** If the user changes `template_adherence`, `page_layouts`, the Master/Layout definition roster, or any `page_pptx_layouts` assignment, repeat the Strategist preflight in [`strategist.md`](../references/strategist.md) §6.2 before approval and hand-back. Every newly selected prototype must declare root Master/Layout identity, direct atomic Master/Layout visuals, and valid top-level slot groups with positive bounds plus one compatible carrier or explicit composite `object` proxy. A zero-slot Layout is valid. Update `pptx_masters`, unique `pptx_layouts` definitions, and complete `page_pptx_layouts` assignments in both artifacts immediately. A legacy prototype must run [`restore-pptx-structure`](./restore-pptx-structure.md); do not create a fallback mode inside refinement. --- diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/restore-pptx-structure.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/restore-pptx-structure.md index b5ae3e78..dcee5e28 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/restore-pptx-structure.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/restore-pptx-structure.md @@ -6,7 +6,7 @@ description: Restore legacy SVG projects to the explicit structured Master/Layou Restore an existing SVG-authored project or template before quality checking or release export when its Master/Layout contract is absent or legacy. -**Trigger**: Run when `svg_quality_checker.py` or `svg_to_pptx.py` reports a missing or legacy `pptx_structure.mode`, or when the user explicitly asks to migrate an older SVG project. +**Trigger**: Run when a structured/template project reports a missing or legacy `pptx_structure.mode`, or when the user explicitly asks to migrate an older structured SVG project. Do not run for a current free-design/brand-only project that explicitly declares `pptx_structure.mode: flat`; missing Master/Layout identity is intentional on that route. **Hard rule — structure, not packaging**: Directory shape is not PowerPoint structure evidence. A current template workspace uses `templates/design_spec.md`; a compatible legacy-flat package uses `design_spec.md` at its root. Do not run this workflow merely to move a flat package into the current workspace shape. @@ -60,11 +60,13 @@ Use this evidence priority: | 2 | Legacy template SVGs or explicit legacy structure metadata | Preserve stable identities and reusable geometry after removing legacy-only fields | | 3 | Completed SVG pages only | Classify deliberately across the full deck; do not let the exporter infer structure | -**Hard rule — reachable native graph only**: The current structured contract -materializes Master/Layout identities through output-page references. If native -evidence contains a Layout unused by every output page, or a Master reachable -only through such Layouts, stop and list the exact identities. Do not silently -drop them, synthesize a carrier page, or claim full source-graph restoration. +**Hard rule — complete native graph**: Preserve every supported native Layout, +including one unused by every output page. Create a definition-only +`layout_.svg` prototype for each otherwise unrepresented Layout and +record it in the unique `pptx_layouts` roster with a +`template:` source. A Master reachable only through such Layouts is +retained through their parent relationship. Do not silently drop identities or +synthesize a generated carrier page. **Hard rule**: Decide from SVG/lock semantics, never from whether `design_spec.md` is at the workspace root or under `templates/`. @@ -148,11 +150,15 @@ After every SVG has its final metadata, replace the legacy structure sections as - master-default: Default Master ## pptx_layouts -- P01: master-default | cover-visual | Cover Visual -- P02: master-default | content-two-column | Two Column +- cover-visual: master-default | Cover Visual | P01 +- content-two-column: master-default | Two Column | P02 + +## page_pptx_layouts +- P01: cover-visual +- P02: content-two-column ``` -**Hard rule**: `pptx_masters` contains every referenced Master key exactly once. `pptx_layouts` contains exactly one row for every generated page. Each row must match that page root's Master key, Layout key, and Layout name. +**Hard rule**: `pptx_masters` contains every Master key exactly once. `pptx_layouts` contains every unique reusable Layout exactly once and declares its Master, picker name, and definition source. `page_pptx_layouts` contains exactly one assignment for every generated page. Each page root must match its assigned Layout definition. A Layout unused by generated pages uses `template:` as its definition source. **Layout identity**: A Layout key is globally unique. Pages may reuse it only when their Layout atoms and slot id/type/index/bounds/binding/carrier contracts are identical. The same display name under two Masters still uses two different keys. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/routing.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/routing.md index 146ddd1c..3716c278 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/routing.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/routing.md @@ -68,7 +68,7 @@ Route selection authority for PPT Master. Use this file before entering the main | Brand identity setup | Brand asset, brand site URL, branded PPTX/PDF, or explicit brand setup request | [`create-brand`](./create-brand.md) | Brand source exists or can be inspected | Complete identity-only workspace under `templates/brands//` | Stop if no brand source or brand intent exists | | Continue a split-mode project | "Continue generating `projects/`" after the planning session | [`resume-execute`](./resume-execute.md) | Project has planning-session artifacts | Execution-session SVG generation and export | Stop if required planning artifacts are missing | | Refine spec before generation | User explicitly asks to refine/review/revise the spec before SVG work, or confirms `refine_spec: true` | [`refine-spec`](./refine-spec.md) | Strategist confirmation stage completed | Revised `design_spec.md` and `spec_lock.md` before Step 5/6 | Stop until user approves the refined spec | -| Restore legacy PowerPoint structure | Existing project/template SVGs use unmapped `baseline`, `preserve`, `layout_strategy: distill`, `data-pptx-layout-kind`, `distilled`/`utility`, direct atomic placeholders, or lack root Master identity | [`restore-pptx-structure`](./restore-pptx-structure.md) before generation/export or before Step 3 template consumption | Legacy SVG project/package exists; original PPTX/native facts are used when available; a flat package directory by itself is not a trigger | Current structured SVG contract plus complete `pptx_masters`/`pptx_layouts` mapping | Stop if structure cannot be restored without an explicit design decision | +| Restore legacy PowerPoint structure | Existing structured/template SVGs use unmapped `baseline`, `preserve`, `layout_strategy: distill`, `data-pptx-layout-kind`, `distilled`/`utility`, direct atomic placeholders, or an incomplete root Master identity | [`restore-pptx-structure`](./restore-pptx-structure.md) before generation/export or before Step 3 template consumption | Legacy structured SVG project/package exists; original PPTX/native facts are used when available; an explicit `mode: flat` free-design/brand-only project and a flat package directory are not triggers | Current structured SVG contract plus unique `pptx_masters` / `pptx_layouts` definitions and complete `page_pptx_layouts` assignments | Stop if structure cannot be restored without an explicit design decision | | Data chart calibration | Generated deck contains data charts | [`verify-charts`](./verify-charts.md) between Step 6 and Step 7 | SVG pages exist | Calibrated chart coordinates before export | Stop on chart geometry errors until fixed | | Object-level animation tuning | User asks for animation order, timing, effects, or object reveal behavior | [`customize-animations`](./customize-animations.md) | SVG groups / exported context exist | `animations.json` or validated animation config | Stop if requested target objects cannot be identified | | Live preview / element selection / annotations | User mentions live preview, preview, visual check in browser, clicking/selecting an element, or applying browser annotations | [`live-preview`](./live-preview.md) | Project exists; for annotation apply, generated SVGs exist | Running preview service or applied annotations plus re-export | Stop only if project path or SVGs are missing | diff --git a/plugins/codex/plugins/shadcn/THIRD_PARTY_SOURCE.json b/plugins/codex/plugins/shadcn/THIRD_PARTY_SOURCE.json index aa0fcf46..a6f22940 100644 --- a/plugins/codex/plugins/shadcn/THIRD_PARTY_SOURCE.json +++ b/plugins/codex/plugins/shadcn/THIRD_PARTY_SOURCE.json @@ -2,8 +2,8 @@ "sourceId": "shadcn", "repo": "https://github.com/shadcn-ui/ui.git", "ref": "main", - "commit": "3cdaa6eb2f0da27aca8598cb752c32d840e06940", + "commit": "bb8ba0daceb717eefc3a6ecb3457f28ca770d138", "adapter": "claude-skill", "sourcePath": "skills/shadcn", - "syncedAt": "2026-07-10T16:00:00Z" + "syncedAt": "2026-07-13T16:00:00Z" } diff --git a/plugins/codex/plugins/ui-ux-pro-max/README.md b/plugins/codex/plugins/ui-ux-pro-max/README.md index d36907d9..eb856ceb 100755 --- a/plugins/codex/plugins/ui-ux-pro-max/README.md +++ b/plugins/codex/plugins/ui-ux-pro-max/README.md @@ -264,7 +264,7 @@ Many users ask about the differences between the open-source and premium version * **Fully Open Source:** Perfect for individual developers, hobbyists, and standard projects. * **Core UI/UX Intelligence:** Full access to 67 UI styles, 161 product types, color palettes, and curated font pairings. * **Smart Recommendations:** Built-in BM25 search engine for highly accurate design matching. -* **Cross-Platform Support:** Stack-specific guidelines supporting 13+ major frameworks (React, Vue, Tailwind, iOS, Android, etc.). +* **Cross-Platform Support:** Stack-specific guidelines supporting 22 major frameworks (React, Vue, Tailwind, iOS, Android, etc.). * **Design System Generation:** Instantly generate tailored UI rules, patterns, and logic via CLI. ### 🟡 Premium Version @@ -314,6 +314,7 @@ uipro init --ai droid # Droid (Factory) uipro init --ai kilocode # KiloCode uipro init --ai warp # Warp uipro init --ai augment # Augment +uipro init --ai codewhale # CodeWhale uipro init --ai all # All assistants ``` @@ -353,7 +354,7 @@ If it is missing, install it yourself from [python.org](https://www.python.org/d ### Skill Mode (Auto-activate) -**Supported:** Claude Code, Cursor, Windsurf, Antigravity, Codex CLI, Continue, Gemini CLI, OpenCode, Qoder, CodeBuddy, Droid (Factory), KiloCode, Warp, Augment +**Supported:** Claude Code, Cursor, Windsurf, Antigravity, Codex CLI, Continue, Gemini CLI, OpenCode, Qoder, CodeBuddy, Droid (Factory), KiloCode, Warp, Augment, CodeWhale The skill activates automatically when you request UI/UX work. Just chat naturally: @@ -407,7 +408,7 @@ The skill provides stack-specific guidelines for: | **Angular** | Angular | | **PHP** | Laravel (Blade, Livewire, Inertia.js) | | **Other Web** | Svelte, Astro, Three.js | -| **Desktop** | JavaFX | +| **Desktop** | JavaFX, WPF, WinUI 3, Avalonia, Uno Platform, UWP | | **iOS** | SwiftUI | | **Android** | Jetpack Compose | | **Cross-Platform** | React Native, Flutter | @@ -607,11 +608,10 @@ The search scripts require Python 3.x. Install it manually from [python.org](htt ### Design system output is cut off / fields truncated -Use the `--max-length` flag to increase (or remove) the truncation limit: +Human-readable output truncates long fields at 300 characters. Use `--json` to get the full, untruncated data: ```bash -python3 .claude/skills/ui-ux-pro-max/scripts/search.py "SaaS" --domain style --max-length 0 -# ^ 0 = unlimited +python3 .claude/skills/ui-ux-pro-max/scripts/search.py "SaaS" --domain style --json ``` --- diff --git a/plugins/codex/plugins/ui-ux-pro-max/THIRD_PARTY_SOURCE.json b/plugins/codex/plugins/ui-ux-pro-max/THIRD_PARTY_SOURCE.json index bd47f5fe..2308e2a2 100644 --- a/plugins/codex/plugins/ui-ux-pro-max/THIRD_PARTY_SOURCE.json +++ b/plugins/codex/plugins/ui-ux-pro-max/THIRD_PARTY_SOURCE.json @@ -2,8 +2,8 @@ "sourceId": "ui-ux-pro-max", "repo": "https://github.com/nextlevelbuilder/ui-ux-pro-max-skill.git", "ref": "main", - "commit": "3da52ff1cab1be91848072ec1be5f493d730fd5f", + "commit": "0468898265b1552e19f96e9da448e971b6d325fd", "adapter": "claude-skill", "sourcePath": ".claude/skills/ui-ux-pro-max", - "syncedAt": "2026-07-10T16:00:00Z" + "syncedAt": "2026-07-13T16:00:00Z" }