codewave-openclaw-installer 2.1.13 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/install-lib.mjs +11 -0
- package/bin/install.mjs +60 -2
- package/index.js +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +12 -1
- package/skills/acceptance-doc-entry/SKILL.md +54 -1
- package/skills/ppt-master/SKILL.md +17 -390
- package/skills/ppt-master/projects/.gitkeep +0 -0
- package/skills/ppt-master/references/executor-base.md +4 -3
- package/skills/ppt-master/references/image-generator.md +6 -93
- package/skills/ppt-master/references/strategist.md +5 -8
- package/skills/ppt-master/scripts/README.md +1 -1
- package/skills/ppt-master/scripts/finalize_svg.py +0 -14
- package/skills/ppt-master/scripts/svg_quality_checker.py +8 -169
- package/skills/ppt-master/scripts/svg_to_pptx/pptx_builder.py +1 -7
- package/skills/ppt-master/scripts/svg_to_pptx/pptx_cli.py +0 -14
- package/skills/ppt-master/.env.example +0 -35
- package/skills/ppt-master/README.md +0 -90
- package/skills/ppt-master/audit_report_model_perf.md +0 -213
- package/skills/ppt-master/audit_report_portability.md +0 -90
- package/skills/ppt-master/audit_report_robustness.md +0 -192
- package/skills/ppt-master/audit_report_workflow.md +0 -233
- package/skills/ppt-master/fix_report_bid.md +0 -51
- package/skills/ppt-master/fix_report_scripts.md +0 -41
- package/skills/ppt-master/references/bid-content-example-netease.md +0 -815
- package/skills/ppt-master/references/bid-content-template.md +0 -390
- package/skills/ppt-master/references/bid-example-netease.md +0 -339
- package/skills/ppt-master/references/bid-presentation.md +0 -384
- package/skills/ppt-master/references/bid-svgs/03_toc.svg +0 -38
- package/skills/ppt-master/references/bid-svgs/04_chapter_company.svg +0 -7
- package/skills/ppt-master/references/bid-svgs/05_company_overview.svg +0 -28
- package/skills/ppt-master/references/bid-svgs/06_vision_business.svg +0 -45
- package/skills/ppt-master/references/bid-svgs/07_product_system.svg +0 -52
- package/skills/ppt-master/references/bid-svgs/08_codewave_timeline.svg +0 -29
- package/skills/ppt-master/references/bid-svgs/09_certifications.svg +0 -33
- package/skills/ppt-master/references/bid-svgs/10_client_logos.svg +0 -25
- package/skills/ppt-master/references/bid-svgs/11_brand_mission.svg +0 -14
- package/skills/ppt-master/references/bid-svgs/12_chapter_demand.svg +0 -7
- package/skills/ppt-master/references/bid-svgs/16_chapter_advantages.svg +0 -7
- package/skills/ppt-master/references/bid-svgs/18_platform_arch.svg +0 -24
- package/skills/ppt-master/references/bid-svgs/19_function_matrix.svg +0 -35
- package/skills/ppt-master/references/bid-svgs/20_dev_arch.svg +0 -29
- package/skills/ppt-master/references/bid-svgs/21_source_code.svg +0 -25
- package/skills/ppt-master/references/bid-svgs/22_ai_dev.svg +0 -27
- package/skills/ppt-master/references/bid-svgs/23_asset_market.svg +0 -33
- package/skills/ppt-master/references/bid-svgs/24_multi_org.svg +0 -28
- package/skills/ppt-master/references/bid-svgs/25_i18n.svg +0 -22
- package/skills/ppt-master/references/bid-svgs/26_multi_tenant.svg +0 -25
- package/skills/ppt-master/references/bid-svgs/27_integration.svg +0 -27
- package/skills/ppt-master/references/bid-svgs/28_permission.svg +0 -31
- package/skills/ppt-master/references/bid-svgs/29_security.svg +0 -25
- package/skills/ppt-master/references/bid-svgs/30_ai_capabilities.svg +0 -21
- package/skills/ppt-master/references/bid-svgs/31_product_combo.svg +0 -25
- package/skills/ppt-master/references/bid-svgs/32_digital_transform.svg +0 -28
- package/skills/ppt-master/references/bid-svgs/33_chapter_cases.svg +0 -7
- package/skills/ppt-master/references/bid-svgs/34_cummins_case.svg +0 -23
- package/skills/ppt-master/references/bid-svgs/35_cpq_cost.svg +0 -22
- package/skills/ppt-master/references/bid-svgs/36_tech_platform.svg +0 -18
- package/skills/ppt-master/references/bid-svgs/37_platform_value.svg +0 -24
- package/skills/ppt-master/references/bid-svgs/38_operation_plan.svg +0 -25
- package/skills/ppt-master/references/bid-svgs/39_zpmc_case.svg +0 -21
- package/skills/ppt-master/references/bid-svgs/40_zpmc_apps.svg +0 -23
- package/skills/ppt-master/references/bid-svgs/41_chapter_service.svg +0 -7
- package/skills/ppt-master/references/bid-svgs/42_tech_support.svg +0 -24
- package/skills/ppt-master/references/bid-svgs/43_knowledge_transfer.svg +0 -25
- package/skills/ppt-master/references/bid-svgs/44_operation_promotion.svg +0 -20
- package/skills/ppt-master/references/bid-svgs/45_custom_dev_guide.svg +0 -24
- package/skills/ppt-master/references/bid-svgs/46_sla_guarantee.svg +0 -18
- package/skills/ppt-master/references/bid-svgs/47_strategic_cooperation.svg +0 -25
- package/skills/ppt-master/references/bid-svgs/48_ecosystem.svg +0 -24
- package/skills/ppt-master/references/bid-svgs/49_chapter_delivery.svg +0 -23
- package/skills/ppt-master/references/bid-svgs/53_pm_intro.svg +0 -24
- package/skills/ppt-master/references/bid-svgs/54_after_sales.svg +0 -27
- package/skills/ppt-master/references/bid-svgs/55_ending.svg +0 -8
- package/skills/ppt-master/references/company_intro.md +0 -93
- package/skills/ppt-master/references/company_intro_images/slide1_img00.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img01.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img02.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img03.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img04.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img05.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img06.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img07.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img08.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img09.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img10.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img11.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img12.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img13.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img14.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img15.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img16.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img17.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img18.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img19.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img20.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img21.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img22.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img23.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img24.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img25.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img26.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img27.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img28.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img29.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide2_img30.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide2_img31.jpg +0 -0
- package/skills/ppt-master/references/company_intro_images/slide3_img32.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide3_img33.png +0 -0
- package/skills/ppt-master/references/drawio-integration.md +0 -144
- package/skills/ppt-master/requirements.txt +0 -19
- package/skills/ppt-master/resources/backgrounds/chapter_bg.png +0 -0
- package/skills/ppt-master/resources/backgrounds/company_bg.png +0 -0
- package/skills/ppt-master/resources/backgrounds/cover_bg.png +0 -0
- package/skills/ppt-master/resources/backgrounds/index.json +0 -40
- package/skills/ppt-master/resources/backgrounds/tech_bg.png +0 -0
- package/skills/ppt-master/scripts/__pycache__/config.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/__pycache__/error_helper.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/__pycache__/pptx_animations.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/__pycache__/project_utils.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/arch_diagram.py +0 -370
- package/skills/ppt-master/scripts/bid_init.py +0 -79
- package/skills/ppt-master/scripts/drawio_gen.py +0 -366
- package/skills/ppt-master/scripts/drawio_to_svg.py +0 -458
- package/skills/ppt-master/scripts/image_backends/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/image_backends/__pycache__/backend_aigw_gemini.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/image_backends/__pycache__/backend_common.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_finalize/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_finalize/__pycache__/crop_images.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_finalize/__pycache__/embed_icons.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_finalize/__pycache__/embed_images.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_finalize/__pycache__/fix_image_aspect.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_finalize/__pycache__/flatten_tspan.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_finalize/__pycache__/svg_rect_to_path.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_page_gen.py +0 -871
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_context.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_converter.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_elements.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_paths.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_styles.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_utils.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_builder.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_cli.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_dimensions.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_discovery.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_media.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_notes.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_slide_xml.cpython-314.pyc +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204}/01_cover.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204}/02_chapter.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204}/02_toc.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204}/03_content.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204}/04_ending.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204}/design_spec.md" +0 -0
- /package/skills/ppt-master/templates/layouts//{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" → 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"} +0 -0
- /package/skills/ppt-master/templates/layouts//{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" → 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"} +0 -0
- /package/skills/ppt-master/templates/layouts//{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" → 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"} +0 -0
- /package/skills/ppt-master/templates/layouts//{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" → 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"} +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243}/01_cover.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243}/02_chapter.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243}/02_toc.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243}/03_content.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243}/04_ending.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243}/design_spec.md" +0 -0
- /package/skills/ppt-master/templates/layouts//{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" → 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"} +0 -0
- /package/skills/ppt-master/templates/layouts//{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" → 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"} +0 -0
- /package/skills/ppt-master/templates/layouts//{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" → 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"} +0 -0
- /package/skills/ppt-master/templates/layouts//{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" → 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"} +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241}/01_cover.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241}/02_chapter.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241}/02_toc.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241}/03_content.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241}/04_ending.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241}/design_spec.md" +0 -0
- /package/skills/ppt-master/templates/layouts//{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" → 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"} +0 -0
- /package/skills/ppt-master/templates/layouts//{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" → 344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241//345/244/247/345/236/213 logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204}/01_cover.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204}/02_chapter.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204}/02_toc.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204}/03_content.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204}/04_ending.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204}/design_spec.md" +0 -0
- /package/skills/ppt-master/templates/layouts//{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" → 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"} +0 -0
- /package/skills/ppt-master/templates/layouts//{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" → 344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204//345/244/247/345/236/213 logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243}/01_cover.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243}/02_chapter.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243}/02_toc.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243}/03_content.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243}/04_ending.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243}/design_spec.md" +0 -0
- /package/skills/ppt-master/templates/layouts//{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" → 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"} +0 -0
- /package/skills/ppt-master/templates/layouts//{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" → 344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243//345/244/247/345/236/213 logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 346/213/233/345/225/206/351/223/266/350/241/214}/01_cover.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 346/213/233/345/225/206/351/223/266/350/241/214}/02_chapter.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 346/213/233/345/225/206/351/223/266/350/241/214}/02_toc.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 346/213/233/345/225/206/351/223/266/350/241/214}/03_content.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 346/213/233/345/225/206/351/223/266/350/241/214}/04_ending.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 346/213/233/345/225/206/351/223/266/350/241/214}/design_spec.md" +0 -0
- /package/skills/ppt-master/templates/layouts//{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" → 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"} +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 347/247/221/346/212/200/350/223/235/345/225/206/345/212/241}/01_cover.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 347/247/221/346/212/200/350/223/235/345/225/206/345/212/241}/02_chapter.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 347/247/221/346/212/200/350/223/235/345/225/206/345/212/241}/02_toc.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 347/247/221/346/212/200/350/223/235/345/225/206/345/212/241}/03_content.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 347/247/221/346/212/200/350/223/235/345/225/206/345/212/241}/04_ending.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{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 → 347/247/221/346/212/200/350/223/235/345/225/206/345/212/241}/design_spec.md" +0 -0
- /package/skills/ppt-master/templates/layouts/{Technology Blue Business/01_cover.svg → /351/207/215/345/272/206/345/244/247/345/255/246/01_cover.svg"} +0 -0
- /package/skills/ppt-master/templates/layouts/{Technology Blue Business/02_chapter.svg → /351/207/215/345/272/206/345/244/247/345/255/246/02_chapter.svg"} +0 -0
- /package/skills/ppt-master/templates/layouts/{Technology Blue Business/02_toc.svg → /351/207/215/345/272/206/345/244/247/345/255/246/02_toc.svg"} +0 -0
- /package/skills/ppt-master/templates/layouts/{Technology Blue Business/03_content.svg → /351/207/215/345/272/206/345/244/247/345/255/246/03_content.svg"} +0 -0
- /package/skills/ppt-master/templates/layouts/{Technology Blue Business/04_ending.svg → /351/207/215/345/272/206/345/244/247/345/255/246/04_ending.svg"} +0 -0
- /package/skills/ppt-master/templates/layouts/{Technology Blue Business/design_spec.md → /351/207/215/345/272/206/345/244/247/345/255/246/design_spec.md"} +0 -0
- /package/skills/ppt-master/templates/layouts/{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" → /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"} +0 -0
- /package/skills/ppt-master/templates/layouts/{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" → /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"} +0 -0
|
@@ -1,370 +0,0 @@
|
|
|
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("&","&").replace("<","<").replace(">",">").replace('"',""")
|
|
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()
|
|
@@ -1,79 +0,0 @@
|
|
|
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()
|