codewave-openclaw-installer 2.1.10 → 2.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/bin/check.mjs +0 -0
  2. package/bin/install.mjs +0 -0
  3. package/package.json +2 -1
  4. package/skills/ppt-master/.env.example +35 -0
  5. package/skills/ppt-master/README.md +90 -0
  6. package/skills/ppt-master/SKILL.md +390 -17
  7. package/skills/ppt-master/audit_report_model_perf.md +213 -0
  8. package/skills/ppt-master/audit_report_portability.md +90 -0
  9. package/skills/ppt-master/audit_report_robustness.md +192 -0
  10. package/skills/ppt-master/audit_report_workflow.md +233 -0
  11. package/skills/ppt-master/fix_report_bid.md +51 -0
  12. package/skills/ppt-master/fix_report_scripts.md +41 -0
  13. package/skills/ppt-master/references/bid-content-example-netease.md +815 -0
  14. package/skills/ppt-master/references/bid-content-template.md +390 -0
  15. package/skills/ppt-master/references/bid-example-netease.md +339 -0
  16. package/skills/ppt-master/references/bid-presentation.md +384 -0
  17. package/skills/ppt-master/references/bid-svgs/03_toc.svg +38 -0
  18. package/skills/ppt-master/references/bid-svgs/04_chapter_company.svg +7 -0
  19. package/skills/ppt-master/references/bid-svgs/05_company_overview.svg +28 -0
  20. package/skills/ppt-master/references/bid-svgs/06_vision_business.svg +45 -0
  21. package/skills/ppt-master/references/bid-svgs/07_product_system.svg +52 -0
  22. package/skills/ppt-master/references/bid-svgs/08_codewave_timeline.svg +29 -0
  23. package/skills/ppt-master/references/bid-svgs/09_certifications.svg +33 -0
  24. package/skills/ppt-master/references/bid-svgs/10_client_logos.svg +25 -0
  25. package/skills/ppt-master/references/bid-svgs/11_brand_mission.svg +14 -0
  26. package/skills/ppt-master/references/bid-svgs/12_chapter_demand.svg +7 -0
  27. package/skills/ppt-master/references/bid-svgs/16_chapter_advantages.svg +7 -0
  28. package/skills/ppt-master/references/bid-svgs/18_platform_arch.svg +24 -0
  29. package/skills/ppt-master/references/bid-svgs/19_function_matrix.svg +35 -0
  30. package/skills/ppt-master/references/bid-svgs/20_dev_arch.svg +29 -0
  31. package/skills/ppt-master/references/bid-svgs/21_source_code.svg +25 -0
  32. package/skills/ppt-master/references/bid-svgs/22_ai_dev.svg +27 -0
  33. package/skills/ppt-master/references/bid-svgs/23_asset_market.svg +33 -0
  34. package/skills/ppt-master/references/bid-svgs/24_multi_org.svg +28 -0
  35. package/skills/ppt-master/references/bid-svgs/25_i18n.svg +22 -0
  36. package/skills/ppt-master/references/bid-svgs/26_multi_tenant.svg +25 -0
  37. package/skills/ppt-master/references/bid-svgs/27_integration.svg +27 -0
  38. package/skills/ppt-master/references/bid-svgs/28_permission.svg +31 -0
  39. package/skills/ppt-master/references/bid-svgs/29_security.svg +25 -0
  40. package/skills/ppt-master/references/bid-svgs/30_ai_capabilities.svg +21 -0
  41. package/skills/ppt-master/references/bid-svgs/31_product_combo.svg +25 -0
  42. package/skills/ppt-master/references/bid-svgs/32_digital_transform.svg +28 -0
  43. package/skills/ppt-master/references/bid-svgs/33_chapter_cases.svg +7 -0
  44. package/skills/ppt-master/references/bid-svgs/34_cummins_case.svg +23 -0
  45. package/skills/ppt-master/references/bid-svgs/35_cpq_cost.svg +22 -0
  46. package/skills/ppt-master/references/bid-svgs/36_tech_platform.svg +18 -0
  47. package/skills/ppt-master/references/bid-svgs/37_platform_value.svg +24 -0
  48. package/skills/ppt-master/references/bid-svgs/38_operation_plan.svg +25 -0
  49. package/skills/ppt-master/references/bid-svgs/39_zpmc_case.svg +21 -0
  50. package/skills/ppt-master/references/bid-svgs/40_zpmc_apps.svg +23 -0
  51. package/skills/ppt-master/references/bid-svgs/41_chapter_service.svg +7 -0
  52. package/skills/ppt-master/references/bid-svgs/42_tech_support.svg +24 -0
  53. package/skills/ppt-master/references/bid-svgs/43_knowledge_transfer.svg +25 -0
  54. package/skills/ppt-master/references/bid-svgs/44_operation_promotion.svg +20 -0
  55. package/skills/ppt-master/references/bid-svgs/45_custom_dev_guide.svg +24 -0
  56. package/skills/ppt-master/references/bid-svgs/46_sla_guarantee.svg +18 -0
  57. package/skills/ppt-master/references/bid-svgs/47_strategic_cooperation.svg +25 -0
  58. package/skills/ppt-master/references/bid-svgs/48_ecosystem.svg +24 -0
  59. package/skills/ppt-master/references/bid-svgs/49_chapter_delivery.svg +23 -0
  60. package/skills/ppt-master/references/bid-svgs/53_pm_intro.svg +24 -0
  61. package/skills/ppt-master/references/bid-svgs/54_after_sales.svg +27 -0
  62. package/skills/ppt-master/references/bid-svgs/55_ending.svg +8 -0
  63. package/skills/ppt-master/references/company_intro.md +93 -0
  64. package/skills/ppt-master/references/company_intro_images/slide1_img00.png +0 -0
  65. package/skills/ppt-master/references/company_intro_images/slide1_img01.png +0 -0
  66. package/skills/ppt-master/references/company_intro_images/slide1_img02.png +0 -0
  67. package/skills/ppt-master/references/company_intro_images/slide1_img03.png +0 -0
  68. package/skills/ppt-master/references/company_intro_images/slide1_img04.png +0 -0
  69. package/skills/ppt-master/references/company_intro_images/slide1_img05.png +0 -0
  70. package/skills/ppt-master/references/company_intro_images/slide1_img06.png +0 -0
  71. package/skills/ppt-master/references/company_intro_images/slide1_img07.png +0 -0
  72. package/skills/ppt-master/references/company_intro_images/slide1_img08.png +0 -0
  73. package/skills/ppt-master/references/company_intro_images/slide1_img09.png +0 -0
  74. package/skills/ppt-master/references/company_intro_images/slide1_img10.png +0 -0
  75. package/skills/ppt-master/references/company_intro_images/slide1_img11.png +0 -0
  76. package/skills/ppt-master/references/company_intro_images/slide1_img12.png +0 -0
  77. package/skills/ppt-master/references/company_intro_images/slide1_img13.png +0 -0
  78. package/skills/ppt-master/references/company_intro_images/slide1_img14.png +0 -0
  79. package/skills/ppt-master/references/company_intro_images/slide1_img15.png +0 -0
  80. package/skills/ppt-master/references/company_intro_images/slide1_img16.png +0 -0
  81. package/skills/ppt-master/references/company_intro_images/slide1_img17.png +0 -0
  82. package/skills/ppt-master/references/company_intro_images/slide1_img18.png +0 -0
  83. package/skills/ppt-master/references/company_intro_images/slide1_img19.png +0 -0
  84. package/skills/ppt-master/references/company_intro_images/slide1_img20.png +0 -0
  85. package/skills/ppt-master/references/company_intro_images/slide1_img21.png +0 -0
  86. package/skills/ppt-master/references/company_intro_images/slide1_img22.png +0 -0
  87. package/skills/ppt-master/references/company_intro_images/slide1_img23.png +0 -0
  88. package/skills/ppt-master/references/company_intro_images/slide1_img24.png +0 -0
  89. package/skills/ppt-master/references/company_intro_images/slide1_img25.png +0 -0
  90. package/skills/ppt-master/references/company_intro_images/slide1_img26.png +0 -0
  91. package/skills/ppt-master/references/company_intro_images/slide1_img27.png +0 -0
  92. package/skills/ppt-master/references/company_intro_images/slide1_img28.png +0 -0
  93. package/skills/ppt-master/references/company_intro_images/slide1_img29.png +0 -0
  94. package/skills/ppt-master/references/company_intro_images/slide2_img30.png +0 -0
  95. package/skills/ppt-master/references/company_intro_images/slide2_img31.jpg +0 -0
  96. package/skills/ppt-master/references/company_intro_images/slide3_img32.png +0 -0
  97. package/skills/ppt-master/references/company_intro_images/slide3_img33.png +0 -0
  98. package/skills/ppt-master/references/drawio-integration.md +144 -0
  99. package/skills/ppt-master/references/executor-base.md +3 -4
  100. package/skills/ppt-master/references/image-generator.md +93 -6
  101. package/skills/ppt-master/references/strategist.md +8 -5
  102. package/skills/ppt-master/requirements.txt +19 -0
  103. package/skills/ppt-master/resources/backgrounds/chapter_bg.png +0 -0
  104. package/skills/ppt-master/resources/backgrounds/company_bg.png +0 -0
  105. package/skills/ppt-master/resources/backgrounds/cover_bg.png +0 -0
  106. package/skills/ppt-master/resources/backgrounds/index.json +40 -0
  107. package/skills/ppt-master/resources/backgrounds/tech_bg.png +0 -0
  108. package/skills/ppt-master/scripts/README.md +1 -1
  109. package/skills/ppt-master/scripts/__pycache__/config.cpython-314.pyc +0 -0
  110. package/skills/ppt-master/scripts/__pycache__/error_helper.cpython-314.pyc +0 -0
  111. package/skills/ppt-master/scripts/__pycache__/pptx_animations.cpython-314.pyc +0 -0
  112. package/skills/ppt-master/scripts/__pycache__/project_utils.cpython-314.pyc +0 -0
  113. package/skills/ppt-master/scripts/arch_diagram.py +370 -0
  114. package/skills/ppt-master/scripts/bid_init.py +79 -0
  115. package/skills/ppt-master/scripts/drawio_gen.py +366 -0
  116. package/skills/ppt-master/scripts/drawio_to_svg.py +458 -0
  117. package/skills/ppt-master/scripts/finalize_svg.py +14 -0
  118. package/skills/ppt-master/scripts/image_backends/__pycache__/__init__.cpython-314.pyc +0 -0
  119. package/skills/ppt-master/scripts/image_backends/__pycache__/backend_aigw_gemini.cpython-314.pyc +0 -0
  120. package/skills/ppt-master/scripts/image_backends/__pycache__/backend_common.cpython-314.pyc +0 -0
  121. package/skills/ppt-master/scripts/svg_finalize/__pycache__/__init__.cpython-314.pyc +0 -0
  122. package/skills/ppt-master/scripts/svg_finalize/__pycache__/crop_images.cpython-314.pyc +0 -0
  123. package/skills/ppt-master/scripts/svg_finalize/__pycache__/embed_icons.cpython-314.pyc +0 -0
  124. package/skills/ppt-master/scripts/svg_finalize/__pycache__/embed_images.cpython-314.pyc +0 -0
  125. package/skills/ppt-master/scripts/svg_finalize/__pycache__/fix_image_aspect.cpython-314.pyc +0 -0
  126. package/skills/ppt-master/scripts/svg_finalize/__pycache__/flatten_tspan.cpython-314.pyc +0 -0
  127. package/skills/ppt-master/scripts/svg_finalize/__pycache__/svg_rect_to_path.cpython-314.pyc +0 -0
  128. package/skills/ppt-master/scripts/svg_page_gen.py +871 -0
  129. package/skills/ppt-master/scripts/svg_quality_checker.py +169 -8
  130. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/__init__.cpython-314.pyc +0 -0
  131. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_context.cpython-314.pyc +0 -0
  132. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_converter.cpython-314.pyc +0 -0
  133. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_elements.cpython-314.pyc +0 -0
  134. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_paths.cpython-314.pyc +0 -0
  135. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_styles.cpython-314.pyc +0 -0
  136. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_utils.cpython-314.pyc +0 -0
  137. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_builder.cpython-314.pyc +0 -0
  138. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_cli.cpython-314.pyc +0 -0
  139. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_dimensions.cpython-314.pyc +0 -0
  140. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_discovery.cpython-314.pyc +0 -0
  141. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_media.cpython-314.pyc +0 -0
  142. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_notes.cpython-314.pyc +0 -0
  143. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_slide_xml.cpython-314.pyc +0 -0
  144. package/skills/ppt-master/scripts/svg_to_pptx/pptx_builder.py +7 -1
  145. package/skills/ppt-master/scripts/svg_to_pptx/pptx_cli.py +14 -0
  146. package/skills/ppt-master/projects/.gitkeep +0 -0
  147. /package/skills/ppt-master/templates/layouts/{/351/207/215/345/272/206/345/244/247/345/255/246/01_cover.svg" → Technology Blue Business/01_cover.svg} +0 -0
  148. /package/skills/ppt-master/templates/layouts/{/351/207/215/345/272/206/345/244/247/345/255/246/02_chapter.svg" → Technology Blue Business/02_chapter.svg} +0 -0
  149. /package/skills/ppt-master/templates/layouts/{/351/207/215/345/272/206/345/244/247/345/255/246/02_toc.svg" → Technology Blue Business/02_toc.svg} +0 -0
  150. /package/skills/ppt-master/templates/layouts/{/351/207/215/345/272/206/345/244/247/345/255/246/03_content.svg" → Technology Blue Business/03_content.svg} +0 -0
  151. /package/skills/ppt-master/templates/layouts/{/351/207/215/345/272/206/345/244/247/345/255/246/04_ending.svg" → Technology Blue Business/04_ending.svg} +0 -0
  152. /package/skills/ppt-master/templates/layouts/{/351/207/215/345/272/206/345/244/247/345/255/246/design_spec.md" → Technology Blue Business/design_spec.md} +0 -0
  153. /package/skills/ppt-master/templates/layouts/{/351/207/215/345/272/206/345/244/247/345/255/246//351/207/215/345/272/206/345/244/247/345/255/246logo.png" → Technology Blue Business//316/230c/314/247i/314/200/317/203/342/225/221a/314/212/317/203n/314/203/302/272/317/203/302/241/302/252logo.png"} +0 -0
  154. /package/skills/ppt-master/templates/layouts/{/351/207/215/345/272/206/345/244/247/345/255/246//351/207/215/345/272/206/345/244/247/345/255/246logo2.png" → Technology Blue Business//316/230c/314/247i/314/200/317/203/342/225/221a/314/212/317/203n/314/203/302/272/317/203/302/241/302/252logo2.png"} +0 -0
  155. /package/skills/ppt-master/templates/layouts//{346/213/233/345/225/206/351/223/266/350/241/214 → 302/265i/314/210/302/242/317/203o/314/200a/314/212/316/230o/314/202/342/225/242/316/246i/314/201i/314/202}/01_cover.svg" +0 -0
  156. /package/skills/ppt-master/templates/layouts//{346/213/233/345/225/206/351/223/266/350/241/214 → 302/265i/314/210/302/242/317/203o/314/200a/314/212/316/230o/314/202/342/225/242/316/246i/314/201i/314/202}/02_chapter.svg" +0 -0
  157. /package/skills/ppt-master/templates/layouts//{346/213/233/345/225/206/351/223/266/350/241/214 → 302/265i/314/210/302/242/317/203o/314/200a/314/212/316/230o/314/202/342/225/242/316/246i/314/201i/314/202}/02_toc.svg" +0 -0
  158. /package/skills/ppt-master/templates/layouts//{346/213/233/345/225/206/351/223/266/350/241/214 → 302/265i/314/210/302/242/317/203o/314/200a/314/212/316/230o/314/202/342/225/242/316/246i/314/201i/314/202}/03_content.svg" +0 -0
  159. /package/skills/ppt-master/templates/layouts//{346/213/233/345/225/206/351/223/266/350/241/214 → 302/265i/314/210/302/242/317/203o/314/200a/314/212/316/230o/314/202/342/225/242/316/246i/314/201i/314/202}/04_ending.svg" +0 -0
  160. /package/skills/ppt-master/templates/layouts//{346/213/233/345/225/206/351/223/266/350/241/214 → 302/265i/314/210/302/242/317/203o/314/200a/314/212/316/230o/314/202/342/225/242/316/246i/314/201i/314/202}/design_spec.md" +0 -0
  161. /package/skills/ppt-master/templates/layouts//{346/213/233/345/225/206/351/223/266/350/241/214//346/213/233/345/225/206/351/223/266/350/241/214/345/205/254/345/217/270/351/207/221/350/236/215.png" → 302/265i/314/210/302/242/317/203o/314/200a/314/212/316/230o/314/202/342/225/242/316/246i/314/201i/314/202//302/265i/314/210/302/242/317/203o/314/200a/314/212/316/230o/314/202/342/225/242/316/246i/314/201i/314/202/317/203a/314/200/302/274/317/203A/314/212/342/225/225/316/230c/314/247/303/246/316/246/342/202/247i/314/200.png"} +0 -0
  162. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203o/314/200a/314/212/317/203e/314/200i/314/201}/01_cover.svg" +0 -0
  163. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203o/314/200a/314/212/317/203e/314/200i/314/201}/02_chapter.svg" +0 -0
  164. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203o/314/200a/314/212/317/203e/314/200i/314/201}/02_toc.svg" +0 -0
  165. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203o/314/200a/314/212/317/203e/314/200i/314/201}/03_content.svg" +0 -0
  166. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203o/314/200a/314/212/317/203e/314/200i/314/201}/04_ending.svg" +0 -0
  167. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203o/314/200a/314/212/317/203e/314/200i/314/201}/design_spec.md" +0 -0
  168. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241//345/217/263/344/270/212/350/247/222 logo.png" → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203o/314/200a/314/212/317/203e/314/200i/314/201//317/203A/314/212/342/224/202/316/243/342/225/225e/314/200/316/246/302/272/303/206 logo.png"} +0 -0
  169. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241//345/244/247/345/236/213 logo.png" → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203o/314/200a/314/212/317/203e/314/200i/314/201//317/203n/314/203/302/272/317/203/342/202/247i/314/210 logo.png"} +0 -0
  170. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210}/01_cover.svg" +0 -0
  171. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210}/02_chapter.svg" +0 -0
  172. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210}/02_toc.svg" +0 -0
  173. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210}/03_content.svg" +0 -0
  174. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210}/04_ending.svg" +0 -0
  175. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210}/design_spec.md" +0 -0
  176. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204//345/217/263/344/270/212/350/247/222 logo.png" → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210//317/203A/314/212/342/224/202/316/243/342/225/225e/314/200/316/246/302/272/303/206 logo.png"} +0 -0
  177. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204//345/244/247/345/236/213 logo.png" → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210//317/203n/314/203/302/272/317/203/342/202/247i/314/210 logo.png"} +0 -0
  178. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201}/01_cover.svg" +0 -0
  179. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201}/02_chapter.svg" +0 -0
  180. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201}/02_toc.svg" +0 -0
  181. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201}/03_content.svg" +0 -0
  182. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201}/04_ending.svg" +0 -0
  183. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243 → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201}/design_spec.md" +0 -0
  184. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243//345/217/263/344/270/212/350/247/222 logo.png" → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201//317/203A/314/212/342/224/202/316/243/342/225/225e/314/200/316/246/302/272/303/206 logo.png"} +0 -0
  185. /package/skills/ppt-master/templates/layouts//{344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243//345/244/247/345/236/213 logo.png" → 316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201//317/203n/314/203/302/272/317/203/342/202/247i/314/210 logo.png"} +0 -0
  186. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204 → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210}/01_cover.svg" +0 -0
  187. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204 → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210}/02_chapter.svg" +0 -0
  188. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204 → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210}/02_toc.svg" +0 -0
  189. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204 → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210}/03_content.svg" +0 -0
  190. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204 → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210}/04_ending.svg" +0 -0
  191. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204 → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210}/design_spec.md" +0 -0
  192. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204//346/260/264/347/224/265/344/270/211/345/261/200logo.png" → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210//302/265/342/226/221/342/224/244/317/204o/314/210/342/225/241/316/243/342/225/225e/314/210/317/203/342/226/222C/314/247logo.png"} +0 -0
  193. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204//344/270/255/345/233/275/346/260/264/345/212/241logo.png" → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210//316/243/342/225/225/302/241/317/203/302/242/342/225/234/302/265/342/226/221/342/224/244/317/203e/314/200i/314/201logo.png"} +0 -0
  194. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204//345/215/216/344/270/234/351/231/242logo.png" → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210//317/203i/314/200A/314/210/316/243/342/225/225/302/243/316/230O/314/210o/314/201logo.png"} +0 -0
  195. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204//347/224/265/345/273/272logo.png" → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210//317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221logo.png"} +0 -0
  196. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243 → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201}/01_cover.svg" +0 -0
  197. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243 → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201}/02_chapter.svg" +0 -0
  198. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243 → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201}/02_toc.svg" +0 -0
  199. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243 → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201}/03_content.svg" +0 -0
  200. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243 → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201}/04_ending.svg" +0 -0
  201. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243 → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201}/design_spec.md" +0 -0
  202. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243//346/260/264/347/224/265/344/270/211/345/261/200logo.png" → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201//302/265/342/226/221/342/224/244/317/204o/314/210/342/225/241/316/243/342/225/225e/314/210/317/203/342/226/222C/314/247logo.png"} +0 -0
  203. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243//344/270/255/345/233/275/346/260/264/345/212/241logo.png" → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201//316/243/342/225/225/302/241/317/203/302/242/342/225/234/302/265/342/226/221/342/224/244/317/203e/314/200i/314/201logo.png"} +0 -0
  204. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243//345/215/216/344/270/234/351/231/242logo.png" → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201//317/203i/314/200A/314/210/316/243/342/225/225/302/243/316/230O/314/210o/314/201logo.png"} +0 -0
  205. /package/skills/ppt-master/templates/layouts//{344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243//347/224/265/345/273/272logo.png" → 316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201//317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221logo.png"} +0 -0
  206. /package/skills/ppt-master/templates/layouts//{347/247/221/346/212/200/350/223/235/345/225/206/345/212/241 → 317/204/302/272/303/246/302/265e/314/200C/314/247/316/246o/314/202/302/245/317/203o/314/200a/314/212/317/203e/314/200i/314/201}/01_cover.svg" +0 -0
  207. /package/skills/ppt-master/templates/layouts//{347/247/221/346/212/200/350/223/235/345/225/206/345/212/241 → 317/204/302/272/303/246/302/265e/314/200C/314/247/316/246o/314/202/302/245/317/203o/314/200a/314/212/317/203e/314/200i/314/201}/02_chapter.svg" +0 -0
  208. /package/skills/ppt-master/templates/layouts//{347/247/221/346/212/200/350/223/235/345/225/206/345/212/241 → 317/204/302/272/303/246/302/265e/314/200C/314/247/316/246o/314/202/302/245/317/203o/314/200a/314/212/317/203e/314/200i/314/201}/02_toc.svg" +0 -0
  209. /package/skills/ppt-master/templates/layouts//{347/247/221/346/212/200/350/223/235/345/225/206/345/212/241 → 317/204/302/272/303/246/302/265e/314/200C/314/247/316/246o/314/202/302/245/317/203o/314/200a/314/212/317/203e/314/200i/314/201}/03_content.svg" +0 -0
  210. /package/skills/ppt-master/templates/layouts//{347/247/221/346/212/200/350/223/235/345/225/206/345/212/241 → 317/204/302/272/303/246/302/265e/314/200C/314/247/316/246o/314/202/302/245/317/203o/314/200a/314/212/317/203e/314/200i/314/201}/04_ending.svg" +0 -0
  211. /package/skills/ppt-master/templates/layouts//{347/247/221/346/212/200/350/223/235/345/225/206/345/212/241 → 317/204/302/272/303/246/302/265e/314/200C/314/247/316/246o/314/202/302/245/317/203o/314/200a/314/212/317/203e/314/200i/314/201}/design_spec.md" +0 -0
@@ -0,0 +1,370 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ arch_diagram.py - Generate professional multi-zone architecture diagrams as SVG.
4
+
5
+ Two layout modes:
6
+ 1. "layers": Horizontal layer bands stacked vertically (simple)
7
+ 2. "zones": Multi-zone grid layout with titled blocks, side labels, arrows
8
+ (enterprise product architecture style, inspired by Codewave/CoreBridge)
9
+
10
+ Usage:
11
+ python arch_diagram.py <json_file> -o <output.svg> [--title "..."]
12
+
13
+ Zone JSON Schema:
14
+ {
15
+ "title": "平台架构",
16
+ "layout": "zones",
17
+ "grid_cols": 12, "grid_rows": 8,
18
+ "zones": [
19
+ {
20
+ "id": "platform", "label": "开发平台",
21
+ "x": 0, "y": 0, "w": 4, "h": 3,
22
+ "header_color": "#1565C0",
23
+ "brand": "Codewave", // optional brand name top-left
24
+ "sub_label": "智能应用开发平台", // optional subtitle in header
25
+ "columns": [ // multi-column layout inside zone
26
+ {"label": "Web-IDE", "items": ["模型设计器", "逻辑设计器", "页面设计器"]},
27
+ {"label": "管理端", "items": ["资产市场", "集成对接", "多租户管理"]}
28
+ ],
29
+ "items": ["item1", "item2"], // OR flat items (auto-grid)
30
+ "footer": "AI+ 研发智能化" // optional footer text
31
+ }
32
+ ],
33
+ "arrows": [
34
+ {"from": "a", "to": "b", "label": "API调用", "direction": "down|up|left|right|auto",
35
+ "dashed": false, "color": "#78909C", "bidirectional": false}
36
+ ],
37
+ "side_labels": [
38
+ {"text": "安全管理", "side": "left", "y_start": 0, "y_end": 8, "color": "#1565C0"}
39
+ ]
40
+ }
41
+ """
42
+
43
+ import json
44
+ import sys
45
+ import argparse
46
+ import math
47
+
48
+ FONT = "Microsoft YaHei, PingFang SC, Helvetica, Arial, sans-serif"
49
+
50
+
51
+ def _esc(t):
52
+ if not t: return ""
53
+ return str(t).replace("&","&amp;").replace("<","&lt;").replace(">","&gt;").replace('"',"&quot;")
54
+
55
+ def _tw(text, fs=12):
56
+ """Estimate text width."""
57
+ return sum(fs * (1.0 if ord(c)>127 else 0.6) for c in str(text))
58
+
59
+
60
+ # ═══════════════════════════════════════════
61
+ # ZONE MODE
62
+ # ═══════════════════════════════════════════
63
+
64
+ def generate_zone_svg(spec, width=1280, height=720):
65
+ title = spec.get("title","")
66
+ zones = spec.get("zones",[])
67
+ arrows = spec.get("arrows",[])
68
+ side_labels = spec.get("side_labels",[])
69
+
70
+ gc = spec.get("grid_cols",12)
71
+ gr = spec.get("grid_rows",8)
72
+ margin = 20
73
+ title_h = 36 if title else 0
74
+ side_w = 32
75
+ has_left = any(s.get("side")=="left" for s in side_labels)
76
+ has_right = any(s.get("side")=="right" for s in side_labels)
77
+ lw = side_w if has_left else 0
78
+ rw = side_w if has_right else 0
79
+
80
+ cx = margin + lw
81
+ cy = margin + title_h
82
+ cw = width - 2*margin - lw - rw
83
+ ch = height - 2*margin - title_h
84
+ cellw = cw / gc
85
+ cellh = ch / gr
86
+ gap = 5
87
+
88
+ L = [
89
+ f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {width} {height}" width="{width}" height="{height}">',
90
+ f'<defs><filter id="sh" x="-1%" y="-1%" width="102%" height="104%">',
91
+ f'<feDropShadow dx="0" dy="1" stdDeviation="2" flood-opacity="0.08"/></filter></defs>',
92
+ f'<rect width="{width}" height="{height}" fill="#F5F7FA"/>',
93
+ ]
94
+
95
+ if title:
96
+ L.append(f'<text x="{width/2}" y="{margin+20}" text-anchor="middle" '
97
+ f'font-family="{FONT}" font-size="16" font-weight="bold" fill="#1A237E">{_esc(title)}</text>')
98
+
99
+ zr = {} # zone rects for arrows
100
+
101
+ for z in zones:
102
+ zx = cx + z.get("x",0)*cellw + gap
103
+ zy = cy + z.get("y",0)*cellh + gap
104
+ zw = z.get("w",3)*cellw - 2*gap
105
+ zh = z.get("h",2)*cellh - 2*gap
106
+ zr[z["id"]] = (zx, zy, zw, zh)
107
+
108
+ hc = z.get("header_color","#1565C0")
109
+ hh = 28 # header height
110
+ br = 6
111
+
112
+ # Container
113
+ L.append(f'<rect x="{zx:.1f}" y="{zy:.1f}" width="{zw:.1f}" height="{zh:.1f}" '
114
+ f'rx="{br}" fill="#FFFFFF" stroke="#E0E0E0" stroke-width="0.8" filter="url(#sh)"/>')
115
+ # Header bar
116
+ L.append(f'<rect x="{zx:.1f}" y="{zy:.1f}" width="{zw:.1f}" height="{hh}" '
117
+ f'rx="{br}" fill="{hc}"/>')
118
+ L.append(f'<rect x="{zx:.1f}" y="{zy+hh-br:.1f}" width="{zw:.1f}" height="{br}" fill="{hc}"/>')
119
+
120
+ # Brand (top-left in header, smaller)
121
+ brand = z.get("brand")
122
+ lbl = z.get("label", z["id"])
123
+ sub = z.get("sub_label","")
124
+
125
+ if brand:
126
+ L.append(f'<text x="{zx+10:.1f}" y="{zy+hh/2+1:.1f}" dominant-baseline="central" '
127
+ f'font-family="{FONT}" font-size="13" font-weight="bold" fill="rgba(255,255,255,0.95)">{_esc(brand)}</text>')
128
+ # Main label to the right
129
+ bw = _tw(brand, 13) + 16
130
+ L.append(f'<text x="{zx+bw:.1f}" y="{zy+hh/2+1:.1f}" dominant-baseline="central" '
131
+ f'font-family="{FONT}" font-size="11" fill="rgba(255,255,255,0.8)">{_esc(sub or lbl)}</text>')
132
+ else:
133
+ L.append(f'<text x="{zx+zw/2:.1f}" y="{zy+hh/2+1:.1f}" text-anchor="middle" dominant-baseline="central" '
134
+ f'font-family="{FONT}" font-size="14" font-weight="bold" fill="#FFFFFF">{_esc(lbl)}</text>')
135
+
136
+ body_y = zy + hh
137
+ body_h = zh - hh
138
+
139
+ # Footer
140
+ footer = z.get("footer")
141
+ footer_h = 0
142
+ if footer:
143
+ footer_h = 22
144
+ body_h -= footer_h
145
+ fy = zy + zh - footer_h
146
+ L.append(f'<rect x="{zx:.1f}" y="{fy:.1f}" width="{zw:.1f}" height="{footer_h}" '
147
+ f'rx="0" fill="{hc}" opacity="0.08"/>')
148
+ L.append(f'<text x="{zx+zw/2:.1f}" y="{fy+footer_h/2:.1f}" text-anchor="middle" dominant-baseline="central" '
149
+ f'font-family="{FONT}" font-size="10" fill="{hc}">{_esc(footer)}</text>')
150
+
151
+ # Render content
152
+ columns = z.get("columns")
153
+ items = z.get("items")
154
+ sections = z.get("sections") # alias for columns
155
+
156
+ if columns or sections:
157
+ cols = columns or sections
158
+ _render_columns(L, cols, zx, body_y, zw, body_h, hc)
159
+ elif items:
160
+ _render_items_grid(L, items, zx, body_y, zw, body_h)
161
+
162
+ # Arrows
163
+ for a in arrows:
164
+ _arrow(L, a, zr)
165
+
166
+ # Side labels
167
+ for sl in side_labels:
168
+ _side_label(L, sl, margin, cy, ch, width, side_w, cellh)
169
+
170
+ L.append('</svg>')
171
+ return "\n".join(L)
172
+
173
+
174
+ def _render_columns(L, cols, zx, zy, zw, zh, accent):
175
+ """Render multi-column layout inside a zone."""
176
+ n = len(cols)
177
+ pad = 6
178
+ col_gap = 4
179
+ col_w = (zw - 2*pad - (n-1)*col_gap) / n
180
+
181
+ for ci, col in enumerate(cols):
182
+ cx = zx + pad + ci*(col_w + col_gap)
183
+ cy_start = zy + pad
184
+
185
+ # Column sub-header
186
+ clbl = col.get("label","")
187
+ item_y = cy_start
188
+ if clbl:
189
+ L.append(f'<text x="{cx+col_w/2:.1f}" y="{cy_start+12:.1f}" text-anchor="middle" '
190
+ f'font-family="{FONT}" font-size="11" font-weight="bold" fill="{accent}">{_esc(clbl)}</text>')
191
+ item_y = cy_start + 20
192
+
193
+ # Items as pills
194
+ items = col.get("items",[])
195
+ ih = 22
196
+ ig = 4
197
+ for ii, item in enumerate(items):
198
+ iy = item_y + ii*(ih+ig)
199
+ if iy + ih > zy + zh - 6:
200
+ break
201
+ L.append(f'<rect x="{cx+2:.1f}" y="{iy:.1f}" width="{col_w-4:.1f}" height="{ih}" '
202
+ f'rx="4" fill="#F5F7FA" stroke="#E0E4E8" stroke-width="0.5"/>')
203
+ L.append(f'<text x="{cx+col_w/2:.1f}" y="{iy+ih/2:.1f}" text-anchor="middle" dominant-baseline="central" '
204
+ f'font-family="{FONT}" font-size="11" fill="#37474F">{_esc(item)}</text>')
205
+
206
+
207
+ def _render_items_grid(L, items, zx, zy, zw, zh):
208
+ """Render flat items as auto-grid cards."""
209
+ if not items: return
210
+ pad = 8
211
+ ih = 24
212
+ ig = 4
213
+ max_cols = max(1, int((zw - 2*pad) / 100))
214
+ cols = min(len(items), max_cols)
215
+ iw = (zw - 2*pad - (cols-1)*ig) / cols
216
+
217
+ for ii, item in enumerate(items):
218
+ r, c = ii // cols, ii % cols
219
+ ix = zx + pad + c*(iw+ig)
220
+ iy = zy + pad + r*(ih+ig)
221
+ if iy + ih > zy + zh - 4: break
222
+ L.append(f'<rect x="{ix:.1f}" y="{iy:.1f}" width="{iw:.1f}" height="{ih}" '
223
+ f'rx="4" fill="#F0F4F8" stroke="#CFD8DC" stroke-width="0.5"/>')
224
+ L.append(f'<text x="{ix+iw/2:.1f}" y="{iy+ih/2:.1f}" text-anchor="middle" dominant-baseline="central" '
225
+ f'font-family="{FONT}" font-size="11" fill="#37474F">{_esc(item)}</text>')
226
+
227
+
228
+ def _arrow(L, a, zr):
229
+ s = zr.get(a.get("from")); t = zr.get(a.get("to"))
230
+ if not s or not t: return
231
+ sx,sy,sw,sh = s; tx,ty,tw,th = t
232
+ d = a.get("direction","auto")
233
+ color = a.get("color","#78909C")
234
+ label = a.get("label","")
235
+ bi = a.get("bidirectional", False)
236
+ dashed = a.get("dashed", False)
237
+
238
+ if d == "auto":
239
+ dx = (tx+tw/2)-(sx+sw/2); dy = (ty+th/2)-(sy+sh/2)
240
+ d = ("down" if dy>0 else "up") if abs(dy)>abs(dx) else ("right" if dx>0 else "left")
241
+
242
+ pts = {
243
+ "down": (sx+sw/2, sy+sh, tx+tw/2, ty),
244
+ "up": (sx+sw/2, sy, tx+tw/2, ty+th),
245
+ "right": (sx+sw, sy+sh/2, tx, ty+th/2),
246
+ "left": (sx, sy+sh/2, tx+tw, ty+th/2),
247
+ }
248
+ x1,y1,x2,y2 = pts.get(d, pts["down"])
249
+
250
+ da = ' stroke-dasharray="6 4"' if dashed else ""
251
+ L.append(f'<line x1="{x1:.1f}" y1="{y1:.1f}" x2="{x2:.1f}" y2="{y2:.1f}" '
252
+ f'stroke="{color}" stroke-width="1.2"{da}/>')
253
+
254
+ # Arrowhead at end
255
+ _arrowhead(L, x1, y1, x2, y2, color)
256
+ # Bidirectional
257
+ if bi:
258
+ _arrowhead(L, x2, y2, x1, y1, color)
259
+
260
+ if label:
261
+ lx=(x1+x2)/2; ly=(y1+y2)/2-6
262
+ L.append(f'<text x="{lx:.1f}" y="{ly:.1f}" text-anchor="middle" '
263
+ f'font-family="{FONT}" font-size="8" fill="{color}">{_esc(label)}</text>')
264
+
265
+
266
+ def _arrowhead(L, x1, y1, x2, y2, color):
267
+ dx,dy = x2-x1, y2-y1
268
+ ln = max(math.sqrt(dx*dx+dy*dy), 0.001)
269
+ ux,uy = dx/ln, dy/ln
270
+ sz=6; rx,ry = -uy*sz*0.4, ux*sz*0.4
271
+ bx,by = x2-ux*sz, y2-uy*sz
272
+ L.append(f'<polygon points="{x2:.1f},{y2:.1f} {bx+rx:.1f},{by+ry:.1f} '
273
+ f'{bx-rx:.1f},{by-ry:.1f}" fill="{color}"/>')
274
+
275
+
276
+ def _side_label(L, sl, margin, cy, ch, total_w, side_w, cellh):
277
+ side = sl.get("side","left")
278
+ text = sl.get("text","")
279
+ color = sl.get("color","#1565C0")
280
+ bg = sl.get("bg_color", color)
281
+ ys = sl.get("y_start",0); ye = sl.get("y_end",8)
282
+
283
+ lw = side_w - 2
284
+ ly = cy + ys*cellh
285
+ lh = (ye-ys)*cellh
286
+ lx = margin if side=="left" else total_w - margin - lw
287
+
288
+ L.append(f'<rect x="{lx:.1f}" y="{ly:.1f}" width="{lw}" height="{lh:.1f}" '
289
+ f'rx="4" fill="{bg}" opacity="0.12"/>')
290
+ L.append(f'<rect x="{lx:.1f}" y="{ly:.1f}" width="{lw}" height="{lh:.1f}" '
291
+ f'rx="4" fill="none" stroke="{color}" stroke-width="1"/>')
292
+ ccx = lx+lw/2; ccy = ly+lh/2
293
+ L.append(f'<text x="{ccx:.1f}" y="{ccy:.1f}" text-anchor="middle" dominant-baseline="central" '
294
+ f'font-family="{FONT}" font-size="12" font-weight="bold" fill="{color}" '
295
+ f'transform="rotate(-90,{ccx:.1f},{ccy:.1f})" letter-spacing="3">{_esc(text)}</text>')
296
+
297
+
298
+ # ═══════════════════════════════════════════
299
+ # LAYER MODE (backward-compatible)
300
+ # ═══════════════════════════════════════════
301
+
302
+ LAYER_COLORS = [
303
+ ("#E3F2FD","#1565C0","#0D47A1"),
304
+ ("#E8F5E9","#2E7D32","#1B5E20"),
305
+ ("#FFF3E0","#E65100","#BF360C"),
306
+ ("#F3E5F5","#6A1B9A","#4A148C"),
307
+ ("#E0F7FA","#00838F","#006064"),
308
+ ("#FBE9E7","#BF360C","#8D2600"),
309
+ ]
310
+
311
+ def generate_layer_svg(spec, width=1280, height=720, title=""):
312
+ nodes = spec.get("nodes",[]); groups = spec.get("groups",[])
313
+ if not title: title = spec.get("title","")
314
+ gm = {}
315
+ for g in groups: gm[g["id"]] = [n for n in nodes if n.get("group")==g["id"]]
316
+ ag = [g for g in groups if gm.get(g["id"])]
317
+ nl = len(ag)
318
+ if nl==0: return f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {width} {height}"><text x="{width/2}" y="{height/2}" text-anchor="middle">No data</text></svg>'
319
+
320
+ th = 50 if title else 0
321
+ agap = 14; tagaps = (nl-1)*agap
322
+ ah = height-60-th-tagaps; lh = min(ah/nl, 85)
323
+ tth = nl*lh+tagaps; sy = 30+th+(height-60-th-tth)/2
324
+ mx = 50; lw = width-2*mx
325
+
326
+ L = [f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {width} {height}" width="{width}" height="{height}">',
327
+ f'<defs><filter id="sh" x="-2%" y="-2%" width="104%" height="108%"><feDropShadow dx="1" dy="2" stdDeviation="3" flood-opacity="0.1"/></filter></defs>',
328
+ f'<rect width="{width}" height="{height}" fill="#FAFBFC"/>']
329
+ if title:
330
+ L.append(f'<text x="{width/2}" y="{30+24}" text-anchor="middle" font-family="{FONT}" font-size="20" font-weight="bold" fill="#1A237E">{_esc(title)}</text>')
331
+
332
+ y = sy
333
+ for li, g in enumerate(ag):
334
+ ms = gm[g["id"]]
335
+ fi,st,tc = LAYER_COLORS[li%len(LAYER_COLORS)]
336
+ L.append(f'<rect x="{mx}" y="{y:.1f}" width="{lw}" height="{lh:.1f}" rx="8" fill="{fi}" stroke="{st}" stroke-width="1.5" filter="url(#sh)"/>')
337
+ lb = g.get("label",g["id"])
338
+ L.append(f'<text x="{mx+16}" y="{y+lh/2:.1f}" dominant-baseline="central" font-family="{FONT}" font-size="13" font-weight="bold" fill="{tc}">{_esc(lb)}</text>')
339
+ lbw = _tw(lb,13)+30; cpx = mx+lbw+10; cpw = lw-lbw-30
340
+ n = len(ms)
341
+ if n>0:
342
+ cg=10; ch2=min(lh-20,40); cpy=y+(lh-ch2)/2
343
+ tcg=cg*(n-1) if n>1 else 0; cw2=min((cpw-tcg)/n,150)
344
+ ttw=n*cw2+tcg; sx2=cpx+(cpw-ttw)/2
345
+ for ci,m in enumerate(ms):
346
+ xx=sx2+ci*(cw2+cg)
347
+ L.append(f'<rect x="{xx:.1f}" y="{cpy:.1f}" width="{cw2:.1f}" height="{ch2:.1f}" rx="6" fill="#FFF" stroke="{st}" stroke-width="1" stroke-opacity="0.5"/>')
348
+ L.append(f'<text x="{xx+cw2/2:.1f}" y="{cpy+ch2/2:.1f}" text-anchor="middle" dominant-baseline="central" font-family="{FONT}" font-size="11" fill="#333">{_esc(m.get("label",m["id"]))}</text>')
349
+ if li<nl-1:
350
+ ay1=y+lh+2; ay2=ay1+agap-4; ax=width/2
351
+ L.append(f'<line x1="{ax}" y1="{ay1}" x2="{ax}" y2="{ay2}" stroke="#90A4AE" stroke-width="1.5"/>')
352
+ L.append(f'<polygon points="{ax-4},{ay2-4} {ax+4},{ay2-4} {ax},{ay2}" fill="#90A4AE"/>')
353
+ y += lh+agap
354
+ L.append('</svg>')
355
+ return "\n".join(L)
356
+
357
+
358
+ def main():
359
+ p = argparse.ArgumentParser()
360
+ p.add_argument("input"); p.add_argument("-o","--output",required=True)
361
+ p.add_argument("--width",type=int,default=1280); p.add_argument("--height",type=int,default=720)
362
+ p.add_argument("--title",default="")
363
+ a = p.parse_args()
364
+ with open(a.input,"r",encoding="utf-8") as f: spec = json.load(f)
365
+ layout = spec.get("layout","layers")
366
+ svg = generate_zone_svg(spec,a.width,a.height) if layout=="zones" else generate_layer_svg(spec,a.width,a.height,a.title or spec.get("title",""))
367
+ with open(a.output,"w",encoding="utf-8") as f: f.write(svg)
368
+ print(f"OK {a.output} ({layout}, {a.width}x{a.height})")
369
+
370
+ if __name__=="__main__": main()
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Bid Presentation Initializer — copies 46 pre-built fixed SVGs into a project,
4
+ leaving only 9 dynamic/semi-dynamic pages for manual generation.
5
+
6
+ Usage:
7
+ python scripts/bid_init.py <project_path>
8
+
9
+ This copies all fixed SVG templates from references/bid-svgs/ into
10
+ <project_path>/svg_output/, so only the following pages need manual creation:
11
+
12
+ Dynamic (6): 01_cover, 02_response_overview, 13_core_demands,
13
+ 14_business_response, 15_tech_response, 17_project_goals
14
+ Semi-dynamic (3): 50_org_structure, 51_implementation_plan, 52_core_team
15
+
16
+ After running this script, generate only those 9 SVGs manually, then proceed
17
+ to Step 7 (post-processing & export).
18
+ """
19
+
20
+ import sys
21
+ import shutil
22
+ from pathlib import Path
23
+
24
+ SKILL_DIR = Path(__file__).resolve().parent.parent
25
+ BID_SVGS = SKILL_DIR / "references" / "bid-svgs"
26
+
27
+ DYNAMIC_PAGES = {"01_cover", "02_response_overview", "13_core_demands",
28
+ "14_business_response", "15_tech_response", "17_project_goals"}
29
+ SEMI_DYNAMIC_PAGES = {"50_org_structure", "51_implementation_plan", "52_core_team"}
30
+ MANUAL_PAGES = DYNAMIC_PAGES | SEMI_DYNAMIC_PAGES
31
+
32
+
33
+ def main():
34
+ if len(sys.argv) < 2:
35
+ print("Usage: python scripts/bid_init.py <project_path>")
36
+ sys.exit(1)
37
+
38
+ project = Path(sys.argv[1])
39
+ if not project.is_absolute():
40
+ project = Path.cwd() / project
41
+
42
+ svg_out = project / "svg_output"
43
+ svg_out.mkdir(parents=True, exist_ok=True)
44
+
45
+ if not BID_SVGS.exists():
46
+ print(f"[ERROR] bid-svgs directory not found: {BID_SVGS}")
47
+ sys.exit(1)
48
+
49
+ copied = 0
50
+ skipped = 0
51
+ for svg in sorted(BID_SVGS.glob("*.svg")):
52
+ stem = svg.stem
53
+ # Skip if this is a dynamic/semi-dynamic page (shouldn't be in bid-svgs, but safety check)
54
+ if stem in MANUAL_PAGES:
55
+ skipped += 1
56
+ continue
57
+ dest = svg_out / svg.name
58
+ if dest.exists():
59
+ print(f" [SKIP] {svg.name} (already exists)")
60
+ skipped += 1
61
+ continue
62
+ shutil.copy2(svg, dest)
63
+ copied += 1
64
+ print(f" [COPY] {svg.name}")
65
+
66
+ print(f"\n[Done] Copied {copied} fixed SVGs, skipped {skipped}")
67
+ print(f"\n[WARNING] Pre-built SVGs in bid-svgs/ contain company-specific content.")
68
+ print(f" If the bidding company differs from the pre-built content,")
69
+ print(f" you should regenerate ALL pages from scratch using bid-content-template.md.")
70
+ print(f" See references/bid-example-netease.md for a complete example.")
71
+ print(f"\nManual pages to create ({len(MANUAL_PAGES)}):")
72
+ for p in sorted(MANUAL_PAGES):
73
+ indicator = "🔄 dynamic" if p in DYNAMIC_PAGES else "🔀 semi-dynamic"
74
+ exists = "✅" if (svg_out / f"{p}.svg").exists() else "❌"
75
+ print(f" {exists} {p}.svg ({indicator})")
76
+
77
+
78
+ if __name__ == "__main__":
79
+ main()