@amrhas82/agentic-kit 1.0.0

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 (335) hide show
  1. package/.claude-plugin/plugin-lite.json +38 -0
  2. package/.claude-plugin/plugin-pro.json +183 -0
  3. package/.claude-plugin/plugin-standard.json +147 -0
  4. package/.claude-plugin/plugin.json +47 -0
  5. package/LICENSE +21 -0
  6. package/QUICK-START.md +318 -0
  7. package/README.md +449 -0
  8. package/TROUBLESHOOTING.md +788 -0
  9. package/VARIANTS.md +480 -0
  10. package/agents/1-create-prd.md +56 -0
  11. package/agents/2-generate-tasks.md +73 -0
  12. package/agents/3-process-task-list.md +101 -0
  13. package/agents/business-analyst.md +76 -0
  14. package/agents/full-stack-dev.md +80 -0
  15. package/agents/holistic-architect.md +91 -0
  16. package/agents/master.md +55 -0
  17. package/agents/orchestrator.md +103 -0
  18. package/agents/product-manager.md +82 -0
  19. package/agents/product-owner.md +97 -0
  20. package/agents/qa-test-architect.md +72 -0
  21. package/agents/scrum-master.md +64 -0
  22. package/agents/ux-expert.md +74 -0
  23. package/cli.js +230 -0
  24. package/hooks/register-agents.js +123 -0
  25. package/package.json +61 -0
  26. package/resources/agent-teams.yaml +50 -0
  27. package/resources/checklists.md +1724 -0
  28. package/resources/data.md +1372 -0
  29. package/resources/task-briefs.md +4428 -0
  30. package/resources/templates.yaml +5634 -0
  31. package/resources/workflows.yaml +1253 -0
  32. package/skills/algorithmic-art/LICENSE.txt +202 -0
  33. package/skills/algorithmic-art/SKILL.md +405 -0
  34. package/skills/algorithmic-art/templates/generator_template.js +223 -0
  35. package/skills/algorithmic-art/templates/viewer.html +599 -0
  36. package/skills/artifacts-builder/LICENSE.txt +202 -0
  37. package/skills/artifacts-builder/SKILL.md +74 -0
  38. package/skills/artifacts-builder/scripts/bundle-artifact.sh +54 -0
  39. package/skills/artifacts-builder/scripts/init-artifact.sh +322 -0
  40. package/skills/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  41. package/skills/brainstorming/SKILL.md +54 -0
  42. package/skills/brand-guidelines/LICENSE.txt +202 -0
  43. package/skills/brand-guidelines/SKILL.md +73 -0
  44. package/skills/canvas-design/LICENSE.txt +202 -0
  45. package/skills/canvas-design/SKILL.md +130 -0
  46. package/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
  47. package/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
  48. package/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
  49. package/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
  50. package/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
  51. package/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
  52. package/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
  53. package/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
  54. package/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
  55. package/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
  56. package/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
  57. package/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
  58. package/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
  59. package/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
  60. package/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
  61. package/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
  62. package/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
  63. package/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
  64. package/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
  65. package/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
  66. package/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
  67. package/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
  68. package/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
  69. package/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
  70. package/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
  71. package/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
  72. package/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
  73. package/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
  74. package/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
  75. package/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
  76. package/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
  77. package/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
  78. package/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
  79. package/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
  80. package/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
  81. package/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
  82. package/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
  83. package/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
  84. package/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
  85. package/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
  86. package/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
  87. package/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
  88. package/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
  89. package/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
  90. package/skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
  91. package/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
  92. package/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
  93. package/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
  94. package/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
  95. package/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
  96. package/skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
  97. package/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
  98. package/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
  99. package/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
  100. package/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
  101. package/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
  102. package/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
  103. package/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
  104. package/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
  105. package/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
  106. package/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
  107. package/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
  108. package/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
  109. package/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
  110. package/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
  111. package/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
  112. package/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
  113. package/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
  114. package/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
  115. package/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
  116. package/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
  117. package/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
  118. package/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
  119. package/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
  120. package/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
  121. package/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
  122. package/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
  123. package/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
  124. package/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
  125. package/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
  126. package/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
  127. package/skills/code-review/SKILL.md +105 -0
  128. package/skills/code-review/code-reviewer.md +146 -0
  129. package/skills/condition-based-waiting/SKILL.md +120 -0
  130. package/skills/condition-based-waiting/example.ts +158 -0
  131. package/skills/docx/LICENSE.txt +30 -0
  132. package/skills/docx/SKILL.md +197 -0
  133. package/skills/docx/docx-js.md +350 -0
  134. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  135. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  136. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  137. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  138. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  139. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  140. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  141. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  142. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  143. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  144. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  145. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  146. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  147. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  148. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  149. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  150. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  151. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  152. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  153. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  154. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  155. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  156. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  157. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  158. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  159. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  160. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  161. package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  162. package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  163. package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  164. package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  165. package/skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
  166. package/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  167. package/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  168. package/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  169. package/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  170. package/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  171. package/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  172. package/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  173. package/skills/docx/ooxml/scripts/pack.py +159 -0
  174. package/skills/docx/ooxml/scripts/unpack.py +29 -0
  175. package/skills/docx/ooxml/scripts/validate.py +69 -0
  176. package/skills/docx/ooxml/scripts/validation/__init__.py +15 -0
  177. package/skills/docx/ooxml/scripts/validation/base.py +951 -0
  178. package/skills/docx/ooxml/scripts/validation/docx.py +274 -0
  179. package/skills/docx/ooxml/scripts/validation/pptx.py +315 -0
  180. package/skills/docx/ooxml/scripts/validation/redlining.py +279 -0
  181. package/skills/docx/ooxml.md +610 -0
  182. package/skills/docx/scripts/__init__.py +1 -0
  183. package/skills/docx/scripts/document.py +1276 -0
  184. package/skills/docx/scripts/templates/comments.xml +3 -0
  185. package/skills/docx/scripts/templates/commentsExtended.xml +3 -0
  186. package/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  187. package/skills/docx/scripts/templates/commentsIds.xml +3 -0
  188. package/skills/docx/scripts/templates/people.xml +3 -0
  189. package/skills/docx/scripts/utilities.py +374 -0
  190. package/skills/internal-comms/LICENSE.txt +202 -0
  191. package/skills/internal-comms/SKILL.md +32 -0
  192. package/skills/internal-comms/examples/3p-updates.md +47 -0
  193. package/skills/internal-comms/examples/company-newsletter.md +65 -0
  194. package/skills/internal-comms/examples/faq-answers.md +30 -0
  195. package/skills/internal-comms/examples/general-comms.md +16 -0
  196. package/skills/mcp-builder/LICENSE.txt +202 -0
  197. package/skills/mcp-builder/SKILL.md +328 -0
  198. package/skills/mcp-builder/reference/evaluation.md +602 -0
  199. package/skills/mcp-builder/reference/mcp_best_practices.md +915 -0
  200. package/skills/mcp-builder/reference/node_mcp_server.md +916 -0
  201. package/skills/mcp-builder/reference/python_mcp_server.md +752 -0
  202. package/skills/mcp-builder/scripts/connections.py +151 -0
  203. package/skills/mcp-builder/scripts/evaluation.py +373 -0
  204. package/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
  205. package/skills/mcp-builder/scripts/requirements.txt +2 -0
  206. package/skills/pdf/LICENSE.txt +30 -0
  207. package/skills/pdf/SKILL.md +294 -0
  208. package/skills/pdf/forms.md +205 -0
  209. package/skills/pdf/reference.md +612 -0
  210. package/skills/pdf/scripts/check_bounding_boxes.py +70 -0
  211. package/skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
  212. package/skills/pdf/scripts/check_fillable_fields.py +12 -0
  213. package/skills/pdf/scripts/convert_pdf_to_images.py +35 -0
  214. package/skills/pdf/scripts/create_validation_image.py +41 -0
  215. package/skills/pdf/scripts/extract_form_field_info.py +152 -0
  216. package/skills/pdf/scripts/fill_fillable_fields.py +114 -0
  217. package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
  218. package/skills/pptx/LICENSE.txt +30 -0
  219. package/skills/pptx/SKILL.md +484 -0
  220. package/skills/pptx/html2pptx.md +625 -0
  221. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  222. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  223. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  224. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  225. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  226. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  227. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  228. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  229. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  230. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  231. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  232. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  233. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  234. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  235. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  236. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  237. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  238. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  239. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  240. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  241. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  242. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  243. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  244. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  245. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  246. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  247. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  248. package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  249. package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  250. package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  251. package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  252. package/skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
  253. package/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  254. package/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  255. package/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  256. package/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  257. package/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  258. package/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  259. package/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  260. package/skills/pptx/ooxml/scripts/pack.py +159 -0
  261. package/skills/pptx/ooxml/scripts/unpack.py +29 -0
  262. package/skills/pptx/ooxml/scripts/validate.py +69 -0
  263. package/skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
  264. package/skills/pptx/ooxml/scripts/validation/base.py +951 -0
  265. package/skills/pptx/ooxml/scripts/validation/docx.py +274 -0
  266. package/skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
  267. package/skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
  268. package/skills/pptx/ooxml.md +427 -0
  269. package/skills/pptx/scripts/html2pptx.js +979 -0
  270. package/skills/pptx/scripts/inventory.py +1020 -0
  271. package/skills/pptx/scripts/rearrange.py +231 -0
  272. package/skills/pptx/scripts/replace.py +385 -0
  273. package/skills/pptx/scripts/thumbnail.py +450 -0
  274. package/skills/root-cause-tracing/SKILL.md +174 -0
  275. package/skills/root-cause-tracing/find-polluter.sh +63 -0
  276. package/skills/skill-creator/LICENSE.txt +202 -0
  277. package/skills/skill-creator/SKILL.md +209 -0
  278. package/skills/skill-creator/scripts/init_skill.py +303 -0
  279. package/skills/skill-creator/scripts/package_skill.py +110 -0
  280. package/skills/skill-creator/scripts/quick_validate.py +65 -0
  281. package/skills/slack-gif-creator/LICENSE.txt +202 -0
  282. package/skills/slack-gif-creator/SKILL.md +646 -0
  283. package/skills/slack-gif-creator/core/color_palettes.py +302 -0
  284. package/skills/slack-gif-creator/core/easing.py +230 -0
  285. package/skills/slack-gif-creator/core/frame_composer.py +469 -0
  286. package/skills/slack-gif-creator/core/gif_builder.py +246 -0
  287. package/skills/slack-gif-creator/core/typography.py +357 -0
  288. package/skills/slack-gif-creator/core/validators.py +264 -0
  289. package/skills/slack-gif-creator/core/visual_effects.py +494 -0
  290. package/skills/slack-gif-creator/requirements.txt +4 -0
  291. package/skills/slack-gif-creator/templates/bounce.py +106 -0
  292. package/skills/slack-gif-creator/templates/explode.py +331 -0
  293. package/skills/slack-gif-creator/templates/fade.py +329 -0
  294. package/skills/slack-gif-creator/templates/flip.py +291 -0
  295. package/skills/slack-gif-creator/templates/kaleidoscope.py +211 -0
  296. package/skills/slack-gif-creator/templates/morph.py +329 -0
  297. package/skills/slack-gif-creator/templates/move.py +293 -0
  298. package/skills/slack-gif-creator/templates/pulse.py +268 -0
  299. package/skills/slack-gif-creator/templates/shake.py +127 -0
  300. package/skills/slack-gif-creator/templates/slide.py +291 -0
  301. package/skills/slack-gif-creator/templates/spin.py +269 -0
  302. package/skills/slack-gif-creator/templates/wiggle.py +300 -0
  303. package/skills/slack-gif-creator/templates/zoom.py +312 -0
  304. package/skills/systematic-debugging/CREATION-LOG.md +119 -0
  305. package/skills/systematic-debugging/SKILL.md +295 -0
  306. package/skills/systematic-debugging/test-academic.md +14 -0
  307. package/skills/systematic-debugging/test-pressure-1.md +58 -0
  308. package/skills/systematic-debugging/test-pressure-2.md +68 -0
  309. package/skills/systematic-debugging/test-pressure-3.md +69 -0
  310. package/skills/test-driven-development/SKILL.md +364 -0
  311. package/skills/testing-anti-patterns/SKILL.md +302 -0
  312. package/skills/theme-factory/LICENSE.txt +202 -0
  313. package/skills/theme-factory/SKILL.md +59 -0
  314. package/skills/theme-factory/theme-showcase.pdf +0 -0
  315. package/skills/theme-factory/themes/arctic-frost.md +19 -0
  316. package/skills/theme-factory/themes/botanical-garden.md +19 -0
  317. package/skills/theme-factory/themes/desert-rose.md +19 -0
  318. package/skills/theme-factory/themes/forest-canopy.md +19 -0
  319. package/skills/theme-factory/themes/golden-hour.md +19 -0
  320. package/skills/theme-factory/themes/midnight-galaxy.md +19 -0
  321. package/skills/theme-factory/themes/modern-minimalist.md +19 -0
  322. package/skills/theme-factory/themes/ocean-depths.md +19 -0
  323. package/skills/theme-factory/themes/sunset-boulevard.md +19 -0
  324. package/skills/theme-factory/themes/tech-innovation.md +19 -0
  325. package/skills/verification-before-completion/SKILL.md +139 -0
  326. package/skills/webapp-testing/LICENSE.txt +202 -0
  327. package/skills/webapp-testing/SKILL.md +96 -0
  328. package/skills/webapp-testing/examples/console_logging.py +35 -0
  329. package/skills/webapp-testing/examples/element_discovery.py +40 -0
  330. package/skills/webapp-testing/examples/static_html_automation.py +33 -0
  331. package/skills/webapp-testing/scripts/with_server.py +106 -0
  332. package/skills/xlsx/LICENSE.txt +30 -0
  333. package/skills/xlsx/SKILL.md +289 -0
  334. package/skills/xlsx/recalc.py +178 -0
  335. package/validate-references.sh +86 -0
@@ -0,0 +1,494 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Visual Effects - Particles, motion blur, impacts, and other effects for GIFs.
4
+
5
+ This module provides high-impact visual effects that make animations feel
6
+ professional and dynamic while keeping file sizes reasonable.
7
+ """
8
+
9
+ from PIL import Image, ImageDraw, ImageFilter
10
+ import numpy as np
11
+ import math
12
+ import random
13
+ from typing import Optional
14
+
15
+
16
+ class Particle:
17
+ """A single particle in a particle system."""
18
+
19
+ def __init__(self, x: float, y: float, vx: float, vy: float,
20
+ lifetime: float, color: tuple[int, int, int],
21
+ size: int = 3, shape: str = 'circle'):
22
+ """
23
+ Initialize a particle.
24
+
25
+ Args:
26
+ x, y: Starting position
27
+ vx, vy: Velocity
28
+ lifetime: How long particle lives (in frames)
29
+ color: RGB color
30
+ size: Particle size in pixels
31
+ shape: 'circle', 'square', or 'star'
32
+ """
33
+ self.x = x
34
+ self.y = y
35
+ self.vx = vx
36
+ self.vy = vy
37
+ self.lifetime = lifetime
38
+ self.max_lifetime = lifetime
39
+ self.color = color
40
+ self.size = size
41
+ self.shape = shape
42
+ self.gravity = 0.5 # Pixels per frame squared
43
+ self.drag = 0.98 # Velocity multiplier per frame
44
+
45
+ def update(self):
46
+ """Update particle position and lifetime."""
47
+ # Apply physics
48
+ self.vy += self.gravity
49
+ self.vx *= self.drag
50
+ self.vy *= self.drag
51
+
52
+ # Update position
53
+ self.x += self.vx
54
+ self.y += self.vy
55
+
56
+ # Decrease lifetime
57
+ self.lifetime -= 1
58
+
59
+ def is_alive(self) -> bool:
60
+ """Check if particle is still alive."""
61
+ return self.lifetime > 0
62
+
63
+ def get_alpha(self) -> float:
64
+ """Get particle opacity based on lifetime."""
65
+ return max(0, min(1, self.lifetime / self.max_lifetime))
66
+
67
+ def render(self, frame: Image.Image):
68
+ """
69
+ Render particle to frame.
70
+
71
+ Args:
72
+ frame: PIL Image to draw on
73
+ """
74
+ if not self.is_alive():
75
+ return
76
+
77
+ draw = ImageDraw.Draw(frame)
78
+ alpha = self.get_alpha()
79
+
80
+ # Calculate faded color
81
+ color = tuple(int(c * alpha) for c in self.color)
82
+
83
+ # Draw based on shape
84
+ x, y = int(self.x), int(self.y)
85
+ size = max(1, int(self.size * alpha))
86
+
87
+ if self.shape == 'circle':
88
+ bbox = [x - size, y - size, x + size, y + size]
89
+ draw.ellipse(bbox, fill=color)
90
+ elif self.shape == 'square':
91
+ bbox = [x - size, y - size, x + size, y + size]
92
+ draw.rectangle(bbox, fill=color)
93
+ elif self.shape == 'star':
94
+ # Simple 4-point star
95
+ points = [
96
+ (x, y - size),
97
+ (x - size // 2, y),
98
+ (x, y),
99
+ (x, y + size),
100
+ (x, y),
101
+ (x + size // 2, y),
102
+ ]
103
+ draw.line(points, fill=color, width=2)
104
+
105
+
106
+ class ParticleSystem:
107
+ """Manages a collection of particles."""
108
+
109
+ def __init__(self):
110
+ """Initialize particle system."""
111
+ self.particles: list[Particle] = []
112
+
113
+ def emit(self, x: int, y: int, count: int = 10,
114
+ spread: float = 2.0, speed: float = 5.0,
115
+ color: tuple[int, int, int] = (255, 200, 0),
116
+ lifetime: float = 20.0, size: int = 3, shape: str = 'circle'):
117
+ """
118
+ Emit a burst of particles.
119
+
120
+ Args:
121
+ x, y: Emission position
122
+ count: Number of particles to emit
123
+ spread: Angle spread (radians)
124
+ speed: Initial speed
125
+ color: Particle color
126
+ lifetime: Particle lifetime in frames
127
+ size: Particle size
128
+ shape: Particle shape
129
+ """
130
+ for _ in range(count):
131
+ # Random angle and speed
132
+ angle = random.uniform(0, 2 * math.pi)
133
+ vel_mag = random.uniform(speed * 0.5, speed * 1.5)
134
+ vx = math.cos(angle) * vel_mag
135
+ vy = math.sin(angle) * vel_mag
136
+
137
+ # Random lifetime variation
138
+ life = random.uniform(lifetime * 0.7, lifetime * 1.3)
139
+
140
+ particle = Particle(x, y, vx, vy, life, color, size, shape)
141
+ self.particles.append(particle)
142
+
143
+ def emit_confetti(self, x: int, y: int, count: int = 20,
144
+ colors: Optional[list[tuple[int, int, int]]] = None):
145
+ """
146
+ Emit confetti particles (colorful, falling).
147
+
148
+ Args:
149
+ x, y: Emission position
150
+ count: Number of confetti pieces
151
+ colors: List of colors (random if None)
152
+ """
153
+ if colors is None:
154
+ colors = [
155
+ (255, 107, 107), (255, 159, 64), (255, 218, 121),
156
+ (107, 185, 240), (162, 155, 254), (255, 182, 193)
157
+ ]
158
+
159
+ for _ in range(count):
160
+ color = random.choice(colors)
161
+ vx = random.uniform(-3, 3)
162
+ vy = random.uniform(-8, -2)
163
+ shape = random.choice(['square', 'circle'])
164
+ size = random.randint(2, 4)
165
+ lifetime = random.uniform(40, 60)
166
+
167
+ particle = Particle(x, y, vx, vy, lifetime, color, size, shape)
168
+ particle.gravity = 0.3 # Lighter gravity for confetti
169
+ self.particles.append(particle)
170
+
171
+ def emit_sparkles(self, x: int, y: int, count: int = 15):
172
+ """
173
+ Emit sparkle particles (twinkling stars).
174
+
175
+ Args:
176
+ x, y: Emission position
177
+ count: Number of sparkles
178
+ """
179
+ colors = [(255, 255, 200), (255, 255, 255), (255, 255, 150)]
180
+
181
+ for _ in range(count):
182
+ color = random.choice(colors)
183
+ angle = random.uniform(0, 2 * math.pi)
184
+ speed = random.uniform(1, 3)
185
+ vx = math.cos(angle) * speed
186
+ vy = math.sin(angle) * speed
187
+ lifetime = random.uniform(15, 30)
188
+
189
+ particle = Particle(x, y, vx, vy, lifetime, color, 2, 'star')
190
+ particle.gravity = 0
191
+ particle.drag = 0.95
192
+ self.particles.append(particle)
193
+
194
+ def update(self):
195
+ """Update all particles."""
196
+ # Update alive particles
197
+ for particle in self.particles:
198
+ particle.update()
199
+
200
+ # Remove dead particles
201
+ self.particles = [p for p in self.particles if p.is_alive()]
202
+
203
+ def render(self, frame: Image.Image):
204
+ """Render all particles to frame."""
205
+ for particle in self.particles:
206
+ particle.render(frame)
207
+
208
+ def get_particle_count(self) -> int:
209
+ """Get number of active particles."""
210
+ return len(self.particles)
211
+
212
+
213
+ def add_motion_blur(frame: Image.Image, prev_frame: Optional[Image.Image],
214
+ blur_amount: float = 0.5) -> Image.Image:
215
+ """
216
+ Add motion blur by blending with previous frame.
217
+
218
+ Args:
219
+ frame: Current frame
220
+ prev_frame: Previous frame (None for first frame)
221
+ blur_amount: Amount of blur (0.0-1.0)
222
+
223
+ Returns:
224
+ Frame with motion blur applied
225
+ """
226
+ if prev_frame is None:
227
+ return frame
228
+
229
+ # Blend current frame with previous frame
230
+ frame_array = np.array(frame, dtype=np.float32)
231
+ prev_array = np.array(prev_frame, dtype=np.float32)
232
+
233
+ blended = frame_array * (1 - blur_amount) + prev_array * blur_amount
234
+ blended = np.clip(blended, 0, 255).astype(np.uint8)
235
+
236
+ return Image.fromarray(blended)
237
+
238
+
239
+ def create_impact_flash(frame: Image.Image, position: tuple[int, int],
240
+ radius: int = 100, intensity: float = 0.7) -> Image.Image:
241
+ """
242
+ Create a bright flash effect at impact point.
243
+
244
+ Args:
245
+ frame: PIL Image to draw on
246
+ position: Center of flash
247
+ radius: Flash radius
248
+ intensity: Flash intensity (0.0-1.0)
249
+
250
+ Returns:
251
+ Modified frame
252
+ """
253
+ # Create overlay
254
+ overlay = Image.new('RGBA', frame.size, (0, 0, 0, 0))
255
+ draw = ImageDraw.Draw(overlay)
256
+
257
+ x, y = position
258
+
259
+ # Draw concentric circles with decreasing opacity
260
+ num_circles = 5
261
+ for i in range(num_circles):
262
+ alpha = int(255 * intensity * (1 - i / num_circles))
263
+ r = radius * (1 - i / num_circles)
264
+ color = (255, 255, 240, alpha) # Warm white
265
+
266
+ bbox = [x - r, y - r, x + r, y + r]
267
+ draw.ellipse(bbox, fill=color)
268
+
269
+ # Composite onto frame
270
+ frame_rgba = frame.convert('RGBA')
271
+ frame_rgba = Image.alpha_composite(frame_rgba, overlay)
272
+ return frame_rgba.convert('RGB')
273
+
274
+
275
+ def create_shockwave_rings(frame: Image.Image, position: tuple[int, int],
276
+ radii: list[int], color: tuple[int, int, int] = (255, 200, 0),
277
+ width: int = 3) -> Image.Image:
278
+ """
279
+ Create expanding ring effects.
280
+
281
+ Args:
282
+ frame: PIL Image to draw on
283
+ position: Center of rings
284
+ radii: List of ring radii
285
+ color: Ring color
286
+ width: Ring width
287
+
288
+ Returns:
289
+ Modified frame
290
+ """
291
+ draw = ImageDraw.Draw(frame)
292
+ x, y = position
293
+
294
+ for radius in radii:
295
+ bbox = [x - radius, y - radius, x + radius, y + radius]
296
+ draw.ellipse(bbox, outline=color, width=width)
297
+
298
+ return frame
299
+
300
+
301
+ def create_explosion_effect(frame: Image.Image, position: tuple[int, int],
302
+ radius: int, progress: float,
303
+ color: tuple[int, int, int] = (255, 150, 0)) -> Image.Image:
304
+ """
305
+ Create an explosion effect that expands and fades.
306
+
307
+ Args:
308
+ frame: PIL Image to draw on
309
+ position: Explosion center
310
+ radius: Maximum radius
311
+ progress: Animation progress (0.0-1.0)
312
+ color: Explosion color
313
+
314
+ Returns:
315
+ Modified frame
316
+ """
317
+ current_radius = int(radius * progress)
318
+ fade = 1 - progress
319
+
320
+ # Create overlay
321
+ overlay = Image.new('RGBA', frame.size, (0, 0, 0, 0))
322
+ draw = ImageDraw.Draw(overlay)
323
+
324
+ x, y = position
325
+
326
+ # Draw expanding circle with fade
327
+ alpha = int(255 * fade)
328
+ r, g, b = color
329
+ circle_color = (r, g, b, alpha)
330
+
331
+ bbox = [x - current_radius, y - current_radius, x + current_radius, y + current_radius]
332
+ draw.ellipse(bbox, fill=circle_color)
333
+
334
+ # Composite
335
+ frame_rgba = frame.convert('RGBA')
336
+ frame_rgba = Image.alpha_composite(frame_rgba, overlay)
337
+ return frame_rgba.convert('RGB')
338
+
339
+
340
+ def add_glow_effect(frame: Image.Image, mask_color: tuple[int, int, int],
341
+ glow_color: tuple[int, int, int],
342
+ blur_radius: int = 10) -> Image.Image:
343
+ """
344
+ Add a glow effect to areas of a specific color.
345
+
346
+ Args:
347
+ frame: PIL Image
348
+ mask_color: Color to create glow around
349
+ glow_color: Color of glow
350
+ blur_radius: Blur amount
351
+
352
+ Returns:
353
+ Frame with glow
354
+ """
355
+ # Create mask of target color
356
+ frame_array = np.array(frame)
357
+ mask = np.all(frame_array == mask_color, axis=-1)
358
+
359
+ # Create glow layer
360
+ glow = Image.new('RGB', frame.size, (0, 0, 0))
361
+ glow_array = np.array(glow)
362
+ glow_array[mask] = glow_color
363
+ glow = Image.fromarray(glow_array)
364
+
365
+ # Blur the glow
366
+ glow = glow.filter(ImageFilter.GaussianBlur(blur_radius))
367
+
368
+ # Blend with original
369
+ blended = Image.blend(frame, glow, 0.5)
370
+ return blended
371
+
372
+
373
+ def add_drop_shadow(frame: Image.Image, object_bounds: tuple[int, int, int, int],
374
+ shadow_offset: tuple[int, int] = (5, 5),
375
+ shadow_color: tuple[int, int, int] = (0, 0, 0),
376
+ blur: int = 5) -> Image.Image:
377
+ """
378
+ Add drop shadow to an object.
379
+
380
+ Args:
381
+ frame: PIL Image
382
+ object_bounds: (x1, y1, x2, y2) bounds of object
383
+ shadow_offset: (x, y) offset of shadow
384
+ shadow_color: Shadow color
385
+ blur: Shadow blur amount
386
+
387
+ Returns:
388
+ Frame with shadow
389
+ """
390
+ # Extract object
391
+ x1, y1, x2, y2 = object_bounds
392
+ obj = frame.crop((x1, y1, x2, y2))
393
+
394
+ # Create shadow
395
+ shadow = Image.new('RGBA', obj.size, (*shadow_color, 180))
396
+
397
+ # Create frame with alpha
398
+ frame_rgba = frame.convert('RGBA')
399
+
400
+ # Paste shadow
401
+ shadow_pos = (x1 + shadow_offset[0], y1 + shadow_offset[1])
402
+ frame_rgba.paste(shadow, shadow_pos, shadow)
403
+
404
+ # Paste object on top
405
+ frame_rgba.paste(obj, (x1, y1))
406
+
407
+ return frame_rgba.convert('RGB')
408
+
409
+
410
+ def create_speed_lines(frame: Image.Image, position: tuple[int, int],
411
+ direction: float, length: int = 50,
412
+ count: int = 5, color: tuple[int, int, int] = (200, 200, 200)) -> Image.Image:
413
+ """
414
+ Create speed lines for motion effect.
415
+
416
+ Args:
417
+ frame: PIL Image to draw on
418
+ position: Center position
419
+ direction: Angle in radians (0 = right, pi/2 = down)
420
+ length: Line length
421
+ count: Number of lines
422
+ color: Line color
423
+
424
+ Returns:
425
+ Modified frame
426
+ """
427
+ draw = ImageDraw.Draw(frame)
428
+ x, y = position
429
+
430
+ # Opposite direction (lines trail behind)
431
+ trail_angle = direction + math.pi
432
+
433
+ for i in range(count):
434
+ # Offset from center
435
+ offset_angle = trail_angle + random.uniform(-0.3, 0.3)
436
+ offset_dist = random.uniform(10, 30)
437
+ start_x = x + math.cos(offset_angle) * offset_dist
438
+ start_y = y + math.sin(offset_angle) * offset_dist
439
+
440
+ # End point
441
+ line_length = random.uniform(length * 0.7, length * 1.3)
442
+ end_x = start_x + math.cos(trail_angle) * line_length
443
+ end_y = start_y + math.sin(trail_angle) * line_length
444
+
445
+ # Draw line with varying opacity
446
+ alpha = random.randint(100, 200)
447
+ width = random.randint(1, 3)
448
+
449
+ # Simple line (full opacity simulation)
450
+ draw.line([(start_x, start_y), (end_x, end_y)], fill=color, width=width)
451
+
452
+ return frame
453
+
454
+
455
+ def create_screen_shake_offset(intensity: int, frame_index: int) -> tuple[int, int]:
456
+ """
457
+ Calculate screen shake offset for a frame.
458
+
459
+ Args:
460
+ intensity: Shake intensity in pixels
461
+ frame_index: Current frame number
462
+
463
+ Returns:
464
+ (x, y) offset tuple
465
+ """
466
+ # Use frame index for deterministic but random-looking shake
467
+ random.seed(frame_index)
468
+ offset_x = random.randint(-intensity, intensity)
469
+ offset_y = random.randint(-intensity, intensity)
470
+ random.seed() # Reset seed
471
+ return (offset_x, offset_y)
472
+
473
+
474
+ def apply_screen_shake(frame: Image.Image, intensity: int, frame_index: int) -> Image.Image:
475
+ """
476
+ Apply screen shake effect to entire frame.
477
+
478
+ Args:
479
+ frame: PIL Image
480
+ intensity: Shake intensity
481
+ frame_index: Current frame number
482
+
483
+ Returns:
484
+ Shaken frame
485
+ """
486
+ offset_x, offset_y = create_screen_shake_offset(intensity, frame_index)
487
+
488
+ # Create new frame with background
489
+ shaken = Image.new('RGB', frame.size, (0, 0, 0))
490
+
491
+ # Paste original frame with offset
492
+ shaken.paste(frame, (offset_x, offset_y))
493
+
494
+ return shaken
@@ -0,0 +1,4 @@
1
+ pillow>=10.0.0
2
+ imageio>=2.31.0
3
+ imageio-ffmpeg>=0.4.9
4
+ numpy>=1.24.0
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Bounce Animation Template - Creates bouncing motion for objects.
4
+
5
+ Use this to make objects bounce up and down or horizontally with realistic physics.
6
+ """
7
+
8
+ import sys
9
+ from pathlib import Path
10
+
11
+ # Add parent directory to path
12
+ sys.path.append(str(Path(__file__).parent.parent))
13
+
14
+ from core.gif_builder import GIFBuilder
15
+ from core.frame_composer import create_blank_frame, draw_circle, draw_emoji
16
+ from core.easing import ease_out_bounce, interpolate
17
+
18
+
19
+ def create_bounce_animation(
20
+ object_type: str = 'circle',
21
+ object_data: dict = None,
22
+ num_frames: int = 30,
23
+ bounce_height: int = 150,
24
+ ground_y: int = 350,
25
+ start_x: int = 240,
26
+ frame_width: int = 480,
27
+ frame_height: int = 480,
28
+ bg_color: tuple[int, int, int] = (255, 255, 255)
29
+ ) -> list:
30
+ """
31
+ Create frames for a bouncing animation.
32
+
33
+ Args:
34
+ object_type: 'circle', 'emoji', or 'custom'
35
+ object_data: Data for the object (e.g., {'radius': 30, 'color': (255, 0, 0)})
36
+ num_frames: Number of frames in the animation
37
+ bounce_height: Maximum height of bounce
38
+ ground_y: Y position of ground
39
+ start_x: X position (or starting X if moving horizontally)
40
+ frame_width: Frame width
41
+ frame_height: Frame height
42
+ bg_color: Background color
43
+
44
+ Returns:
45
+ List of frames
46
+ """
47
+ frames = []
48
+
49
+ # Default object data
50
+ if object_data is None:
51
+ if object_type == 'circle':
52
+ object_data = {'radius': 30, 'color': (255, 100, 100)}
53
+ elif object_type == 'emoji':
54
+ object_data = {'emoji': '⚽', 'size': 60}
55
+
56
+ for i in range(num_frames):
57
+ # Create blank frame
58
+ frame = create_blank_frame(frame_width, frame_height, bg_color)
59
+
60
+ # Calculate progress (0.0 to 1.0)
61
+ t = i / (num_frames - 1) if num_frames > 1 else 0
62
+
63
+ # Calculate Y position using bounce easing
64
+ y = ground_y - int(ease_out_bounce(t) * bounce_height)
65
+
66
+ # Draw object
67
+ if object_type == 'circle':
68
+ draw_circle(
69
+ frame,
70
+ center=(start_x, y),
71
+ radius=object_data['radius'],
72
+ fill_color=object_data['color']
73
+ )
74
+ elif object_type == 'emoji':
75
+ draw_emoji(
76
+ frame,
77
+ emoji=object_data['emoji'],
78
+ position=(start_x - object_data['size'] // 2, y - object_data['size'] // 2),
79
+ size=object_data['size']
80
+ )
81
+
82
+ frames.append(frame)
83
+
84
+ return frames
85
+
86
+
87
+ # Example usage
88
+ if __name__ == '__main__':
89
+ print("Creating bouncing ball GIF...")
90
+
91
+ # Create GIF builder
92
+ builder = GIFBuilder(width=480, height=480, fps=20)
93
+
94
+ # Generate bounce animation
95
+ frames = create_bounce_animation(
96
+ object_type='circle',
97
+ object_data={'radius': 40, 'color': (255, 100, 100)},
98
+ num_frames=40,
99
+ bounce_height=200
100
+ )
101
+
102
+ # Add frames to builder
103
+ builder.add_frames(frames)
104
+
105
+ # Save GIF
106
+ builder.save('bounce_test.gif', num_colors=64)