@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.
- package/.claude-plugin/plugin-lite.json +38 -0
- package/.claude-plugin/plugin-pro.json +183 -0
- package/.claude-plugin/plugin-standard.json +147 -0
- package/.claude-plugin/plugin.json +47 -0
- package/LICENSE +21 -0
- package/QUICK-START.md +318 -0
- package/README.md +449 -0
- package/TROUBLESHOOTING.md +788 -0
- package/VARIANTS.md +480 -0
- package/agents/1-create-prd.md +56 -0
- package/agents/2-generate-tasks.md +73 -0
- package/agents/3-process-task-list.md +101 -0
- package/agents/business-analyst.md +76 -0
- package/agents/full-stack-dev.md +80 -0
- package/agents/holistic-architect.md +91 -0
- package/agents/master.md +55 -0
- package/agents/orchestrator.md +103 -0
- package/agents/product-manager.md +82 -0
- package/agents/product-owner.md +97 -0
- package/agents/qa-test-architect.md +72 -0
- package/agents/scrum-master.md +64 -0
- package/agents/ux-expert.md +74 -0
- package/cli.js +230 -0
- package/hooks/register-agents.js +123 -0
- package/package.json +61 -0
- package/resources/agent-teams.yaml +50 -0
- package/resources/checklists.md +1724 -0
- package/resources/data.md +1372 -0
- package/resources/task-briefs.md +4428 -0
- package/resources/templates.yaml +5634 -0
- package/resources/workflows.yaml +1253 -0
- package/skills/algorithmic-art/LICENSE.txt +202 -0
- package/skills/algorithmic-art/SKILL.md +405 -0
- package/skills/algorithmic-art/templates/generator_template.js +223 -0
- package/skills/algorithmic-art/templates/viewer.html +599 -0
- package/skills/artifacts-builder/LICENSE.txt +202 -0
- package/skills/artifacts-builder/SKILL.md +74 -0
- package/skills/artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/skills/artifacts-builder/scripts/init-artifact.sh +322 -0
- package/skills/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/skills/brainstorming/SKILL.md +54 -0
- package/skills/brand-guidelines/LICENSE.txt +202 -0
- package/skills/brand-guidelines/SKILL.md +73 -0
- package/skills/canvas-design/LICENSE.txt +202 -0
- package/skills/canvas-design/SKILL.md +130 -0
- package/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/skills/code-review/SKILL.md +105 -0
- package/skills/code-review/code-reviewer.md +146 -0
- package/skills/condition-based-waiting/SKILL.md +120 -0
- package/skills/condition-based-waiting/example.ts +158 -0
- package/skills/docx/LICENSE.txt +30 -0
- package/skills/docx/SKILL.md +197 -0
- package/skills/docx/docx-js.md +350 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
- package/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/skills/docx/ooxml/scripts/pack.py +159 -0
- package/skills/docx/ooxml/scripts/unpack.py +29 -0
- package/skills/docx/ooxml/scripts/validate.py +69 -0
- package/skills/docx/ooxml/scripts/validation/__init__.py +15 -0
- package/skills/docx/ooxml/scripts/validation/base.py +951 -0
- package/skills/docx/ooxml/scripts/validation/docx.py +274 -0
- package/skills/docx/ooxml/scripts/validation/pptx.py +315 -0
- package/skills/docx/ooxml/scripts/validation/redlining.py +279 -0
- package/skills/docx/ooxml.md +610 -0
- package/skills/docx/scripts/__init__.py +1 -0
- package/skills/docx/scripts/document.py +1276 -0
- package/skills/docx/scripts/templates/comments.xml +3 -0
- package/skills/docx/scripts/templates/commentsExtended.xml +3 -0
- package/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/skills/docx/scripts/templates/commentsIds.xml +3 -0
- package/skills/docx/scripts/templates/people.xml +3 -0
- package/skills/docx/scripts/utilities.py +374 -0
- package/skills/internal-comms/LICENSE.txt +202 -0
- package/skills/internal-comms/SKILL.md +32 -0
- package/skills/internal-comms/examples/3p-updates.md +47 -0
- package/skills/internal-comms/examples/company-newsletter.md +65 -0
- package/skills/internal-comms/examples/faq-answers.md +30 -0
- package/skills/internal-comms/examples/general-comms.md +16 -0
- package/skills/mcp-builder/LICENSE.txt +202 -0
- package/skills/mcp-builder/SKILL.md +328 -0
- package/skills/mcp-builder/reference/evaluation.md +602 -0
- package/skills/mcp-builder/reference/mcp_best_practices.md +915 -0
- package/skills/mcp-builder/reference/node_mcp_server.md +916 -0
- package/skills/mcp-builder/reference/python_mcp_server.md +752 -0
- package/skills/mcp-builder/scripts/connections.py +151 -0
- package/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/skills/pdf/LICENSE.txt +30 -0
- package/skills/pdf/SKILL.md +294 -0
- package/skills/pdf/forms.md +205 -0
- package/skills/pdf/reference.md +612 -0
- package/skills/pdf/scripts/check_bounding_boxes.py +70 -0
- package/skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
- package/skills/pdf/scripts/check_fillable_fields.py +12 -0
- package/skills/pdf/scripts/convert_pdf_to_images.py +35 -0
- package/skills/pdf/scripts/create_validation_image.py +41 -0
- package/skills/pdf/scripts/extract_form_field_info.py +152 -0
- package/skills/pdf/scripts/fill_fillable_fields.py +114 -0
- package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
- package/skills/pptx/LICENSE.txt +30 -0
- package/skills/pptx/SKILL.md +484 -0
- package/skills/pptx/html2pptx.md +625 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
- package/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/skills/pptx/ooxml/scripts/pack.py +159 -0
- package/skills/pptx/ooxml/scripts/unpack.py +29 -0
- package/skills/pptx/ooxml/scripts/validate.py +69 -0
- package/skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
- package/skills/pptx/ooxml/scripts/validation/base.py +951 -0
- package/skills/pptx/ooxml/scripts/validation/docx.py +274 -0
- package/skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
- package/skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
- package/skills/pptx/ooxml.md +427 -0
- package/skills/pptx/scripts/html2pptx.js +979 -0
- package/skills/pptx/scripts/inventory.py +1020 -0
- package/skills/pptx/scripts/rearrange.py +231 -0
- package/skills/pptx/scripts/replace.py +385 -0
- package/skills/pptx/scripts/thumbnail.py +450 -0
- package/skills/root-cause-tracing/SKILL.md +174 -0
- package/skills/root-cause-tracing/find-polluter.sh +63 -0
- package/skills/skill-creator/LICENSE.txt +202 -0
- package/skills/skill-creator/SKILL.md +209 -0
- package/skills/skill-creator/scripts/init_skill.py +303 -0
- package/skills/skill-creator/scripts/package_skill.py +110 -0
- package/skills/skill-creator/scripts/quick_validate.py +65 -0
- package/skills/slack-gif-creator/LICENSE.txt +202 -0
- package/skills/slack-gif-creator/SKILL.md +646 -0
- package/skills/slack-gif-creator/core/color_palettes.py +302 -0
- package/skills/slack-gif-creator/core/easing.py +230 -0
- package/skills/slack-gif-creator/core/frame_composer.py +469 -0
- package/skills/slack-gif-creator/core/gif_builder.py +246 -0
- package/skills/slack-gif-creator/core/typography.py +357 -0
- package/skills/slack-gif-creator/core/validators.py +264 -0
- package/skills/slack-gif-creator/core/visual_effects.py +494 -0
- package/skills/slack-gif-creator/requirements.txt +4 -0
- package/skills/slack-gif-creator/templates/bounce.py +106 -0
- package/skills/slack-gif-creator/templates/explode.py +331 -0
- package/skills/slack-gif-creator/templates/fade.py +329 -0
- package/skills/slack-gif-creator/templates/flip.py +291 -0
- package/skills/slack-gif-creator/templates/kaleidoscope.py +211 -0
- package/skills/slack-gif-creator/templates/morph.py +329 -0
- package/skills/slack-gif-creator/templates/move.py +293 -0
- package/skills/slack-gif-creator/templates/pulse.py +268 -0
- package/skills/slack-gif-creator/templates/shake.py +127 -0
- package/skills/slack-gif-creator/templates/slide.py +291 -0
- package/skills/slack-gif-creator/templates/spin.py +269 -0
- package/skills/slack-gif-creator/templates/wiggle.py +300 -0
- package/skills/slack-gif-creator/templates/zoom.py +312 -0
- package/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/skills/systematic-debugging/SKILL.md +295 -0
- package/skills/systematic-debugging/test-academic.md +14 -0
- package/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/skills/test-driven-development/SKILL.md +364 -0
- package/skills/testing-anti-patterns/SKILL.md +302 -0
- package/skills/theme-factory/LICENSE.txt +202 -0
- package/skills/theme-factory/SKILL.md +59 -0
- package/skills/theme-factory/theme-showcase.pdf +0 -0
- package/skills/theme-factory/themes/arctic-frost.md +19 -0
- package/skills/theme-factory/themes/botanical-garden.md +19 -0
- package/skills/theme-factory/themes/desert-rose.md +19 -0
- package/skills/theme-factory/themes/forest-canopy.md +19 -0
- package/skills/theme-factory/themes/golden-hour.md +19 -0
- package/skills/theme-factory/themes/midnight-galaxy.md +19 -0
- package/skills/theme-factory/themes/modern-minimalist.md +19 -0
- package/skills/theme-factory/themes/ocean-depths.md +19 -0
- package/skills/theme-factory/themes/sunset-boulevard.md +19 -0
- package/skills/theme-factory/themes/tech-innovation.md +19 -0
- package/skills/verification-before-completion/SKILL.md +139 -0
- package/skills/webapp-testing/LICENSE.txt +202 -0
- package/skills/webapp-testing/SKILL.md +96 -0
- package/skills/webapp-testing/examples/console_logging.py +35 -0
- package/skills/webapp-testing/examples/element_discovery.py +40 -0
- package/skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/skills/webapp-testing/scripts/with_server.py +106 -0
- package/skills/xlsx/LICENSE.txt +30 -0
- package/skills/xlsx/SKILL.md +289 -0
- package/skills/xlsx/recalc.py +178 -0
- package/validate-references.sh +86 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Color Palettes - Professional, harmonious color schemes for GIFs.
|
|
4
|
+
|
|
5
|
+
Using consistent, well-designed color palettes makes GIFs look professional
|
|
6
|
+
and polished instead of random and amateurish.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Optional
|
|
10
|
+
import colorsys
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Professional color palettes - hand-picked for GIF compression and visual appeal
|
|
14
|
+
|
|
15
|
+
VIBRANT = {
|
|
16
|
+
'primary': (255, 68, 68), # Bright red
|
|
17
|
+
'secondary': (255, 168, 0), # Bright orange
|
|
18
|
+
'accent': (0, 168, 255), # Bright blue
|
|
19
|
+
'success': (68, 255, 68), # Bright green
|
|
20
|
+
'background': (240, 248, 255), # Alice blue
|
|
21
|
+
'text': (30, 30, 30), # Almost black
|
|
22
|
+
'text_light': (255, 255, 255), # White
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
PASTEL = {
|
|
26
|
+
'primary': (255, 179, 186), # Pastel pink
|
|
27
|
+
'secondary': (255, 223, 186), # Pastel peach
|
|
28
|
+
'accent': (186, 225, 255), # Pastel blue
|
|
29
|
+
'success': (186, 255, 201), # Pastel green
|
|
30
|
+
'background': (255, 250, 240), # Floral white
|
|
31
|
+
'text': (80, 80, 80), # Dark gray
|
|
32
|
+
'text_light': (255, 255, 255), # White
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
DARK = {
|
|
36
|
+
'primary': (255, 100, 100), # Muted red
|
|
37
|
+
'secondary': (100, 200, 255), # Muted blue
|
|
38
|
+
'accent': (255, 200, 100), # Muted gold
|
|
39
|
+
'success': (100, 255, 150), # Muted green
|
|
40
|
+
'background': (30, 30, 35), # Almost black
|
|
41
|
+
'text': (220, 220, 220), # Light gray
|
|
42
|
+
'text_light': (255, 255, 255), # White
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
NEON = {
|
|
46
|
+
'primary': (255, 16, 240), # Neon pink
|
|
47
|
+
'secondary': (0, 255, 255), # Cyan
|
|
48
|
+
'accent': (255, 255, 0), # Yellow
|
|
49
|
+
'success': (57, 255, 20), # Neon green
|
|
50
|
+
'background': (20, 20, 30), # Dark blue-black
|
|
51
|
+
'text': (255, 255, 255), # White
|
|
52
|
+
'text_light': (255, 255, 255), # White
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
PROFESSIONAL = {
|
|
56
|
+
'primary': (0, 122, 255), # System blue
|
|
57
|
+
'secondary': (88, 86, 214), # System purple
|
|
58
|
+
'accent': (255, 149, 0), # System orange
|
|
59
|
+
'success': (52, 199, 89), # System green
|
|
60
|
+
'background': (255, 255, 255), # White
|
|
61
|
+
'text': (0, 0, 0), # Black
|
|
62
|
+
'text_light': (255, 255, 255), # White
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
WARM = {
|
|
66
|
+
'primary': (255, 107, 107), # Coral red
|
|
67
|
+
'secondary': (255, 159, 64), # Orange
|
|
68
|
+
'accent': (255, 218, 121), # Yellow
|
|
69
|
+
'success': (106, 176, 76), # Olive green
|
|
70
|
+
'background': (255, 246, 229), # Warm white
|
|
71
|
+
'text': (51, 51, 51), # Charcoal
|
|
72
|
+
'text_light': (255, 255, 255), # White
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
COOL = {
|
|
76
|
+
'primary': (107, 185, 240), # Sky blue
|
|
77
|
+
'secondary': (130, 202, 157), # Mint
|
|
78
|
+
'accent': (162, 155, 254), # Lavender
|
|
79
|
+
'success': (86, 217, 150), # Aqua green
|
|
80
|
+
'background': (240, 248, 255), # Alice blue
|
|
81
|
+
'text': (45, 55, 72), # Dark slate
|
|
82
|
+
'text_light': (255, 255, 255), # White
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
MONOCHROME = {
|
|
86
|
+
'primary': (80, 80, 80), # Dark gray
|
|
87
|
+
'secondary': (130, 130, 130), # Medium gray
|
|
88
|
+
'accent': (180, 180, 180), # Light gray
|
|
89
|
+
'success': (100, 100, 100), # Gray
|
|
90
|
+
'background': (245, 245, 245), # Off-white
|
|
91
|
+
'text': (30, 30, 30), # Almost black
|
|
92
|
+
'text_light': (255, 255, 255), # White
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
# Map of palette names
|
|
96
|
+
PALETTES = {
|
|
97
|
+
'vibrant': VIBRANT,
|
|
98
|
+
'pastel': PASTEL,
|
|
99
|
+
'dark': DARK,
|
|
100
|
+
'neon': NEON,
|
|
101
|
+
'professional': PROFESSIONAL,
|
|
102
|
+
'warm': WARM,
|
|
103
|
+
'cool': COOL,
|
|
104
|
+
'monochrome': MONOCHROME,
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def get_palette(name: str = 'vibrant') -> dict:
|
|
109
|
+
"""
|
|
110
|
+
Get a color palette by name.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
name: Palette name (vibrant, pastel, dark, neon, professional, warm, cool, monochrome)
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
Dictionary of color roles to RGB tuples
|
|
117
|
+
"""
|
|
118
|
+
return PALETTES.get(name.lower(), VIBRANT)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def get_text_color_for_background(bg_color: tuple[int, int, int]) -> tuple[int, int, int]:
|
|
122
|
+
"""
|
|
123
|
+
Get the best text color (black or white) for a given background.
|
|
124
|
+
|
|
125
|
+
Uses luminance calculation to ensure readability.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
bg_color: Background RGB color
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
Text color (black or white) that contrasts well
|
|
132
|
+
"""
|
|
133
|
+
# Calculate relative luminance
|
|
134
|
+
r, g, b = bg_color
|
|
135
|
+
luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255
|
|
136
|
+
|
|
137
|
+
# Return black for light backgrounds, white for dark
|
|
138
|
+
return (0, 0, 0) if luminance > 0.5 else (255, 255, 255)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def get_complementary_color(color: tuple[int, int, int]) -> tuple[int, int, int]:
|
|
142
|
+
"""
|
|
143
|
+
Get the complementary (opposite) color on the color wheel.
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
color: RGB color tuple
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
Complementary RGB color
|
|
150
|
+
"""
|
|
151
|
+
# Convert to HSV
|
|
152
|
+
r, g, b = [x / 255.0 for x in color]
|
|
153
|
+
h, s, v = colorsys.rgb_to_hsv(r, g, b)
|
|
154
|
+
|
|
155
|
+
# Rotate hue by 180 degrees (0.5 in 0-1 scale)
|
|
156
|
+
h_comp = (h + 0.5) % 1.0
|
|
157
|
+
|
|
158
|
+
# Convert back to RGB
|
|
159
|
+
r_comp, g_comp, b_comp = colorsys.hsv_to_rgb(h_comp, s, v)
|
|
160
|
+
return (int(r_comp * 255), int(g_comp * 255), int(b_comp * 255))
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def lighten_color(color: tuple[int, int, int], amount: float = 0.3) -> tuple[int, int, int]:
|
|
164
|
+
"""
|
|
165
|
+
Lighten a color by a given amount.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
color: RGB color tuple
|
|
169
|
+
amount: Amount to lighten (0.0-1.0)
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
Lightened RGB color
|
|
173
|
+
"""
|
|
174
|
+
r, g, b = color
|
|
175
|
+
r = min(255, int(r + (255 - r) * amount))
|
|
176
|
+
g = min(255, int(g + (255 - g) * amount))
|
|
177
|
+
b = min(255, int(b + (255 - b) * amount))
|
|
178
|
+
return (r, g, b)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def darken_color(color: tuple[int, int, int], amount: float = 0.3) -> tuple[int, int, int]:
|
|
182
|
+
"""
|
|
183
|
+
Darken a color by a given amount.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
color: RGB color tuple
|
|
187
|
+
amount: Amount to darken (0.0-1.0)
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
Darkened RGB color
|
|
191
|
+
"""
|
|
192
|
+
r, g, b = color
|
|
193
|
+
r = max(0, int(r * (1 - amount)))
|
|
194
|
+
g = max(0, int(g * (1 - amount)))
|
|
195
|
+
b = max(0, int(b * (1 - amount)))
|
|
196
|
+
return (r, g, b)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def blend_colors(color1: tuple[int, int, int], color2: tuple[int, int, int],
|
|
200
|
+
ratio: float = 0.5) -> tuple[int, int, int]:
|
|
201
|
+
"""
|
|
202
|
+
Blend two colors together.
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
color1: First RGB color
|
|
206
|
+
color2: Second RGB color
|
|
207
|
+
ratio: Blend ratio (0.0 = all color1, 1.0 = all color2)
|
|
208
|
+
|
|
209
|
+
Returns:
|
|
210
|
+
Blended RGB color
|
|
211
|
+
"""
|
|
212
|
+
r1, g1, b1 = color1
|
|
213
|
+
r2, g2, b2 = color2
|
|
214
|
+
|
|
215
|
+
r = int(r1 * (1 - ratio) + r2 * ratio)
|
|
216
|
+
g = int(g1 * (1 - ratio) + g2 * ratio)
|
|
217
|
+
b = int(b1 * (1 - ratio) + b2 * ratio)
|
|
218
|
+
|
|
219
|
+
return (r, g, b)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def create_gradient_colors(start_color: tuple[int, int, int],
|
|
223
|
+
end_color: tuple[int, int, int],
|
|
224
|
+
steps: int) -> list[tuple[int, int, int]]:
|
|
225
|
+
"""
|
|
226
|
+
Create a gradient of colors between two colors.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
start_color: Starting RGB color
|
|
230
|
+
end_color: Ending RGB color
|
|
231
|
+
steps: Number of gradient steps
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
List of RGB colors forming gradient
|
|
235
|
+
"""
|
|
236
|
+
colors = []
|
|
237
|
+
for i in range(steps):
|
|
238
|
+
ratio = i / (steps - 1) if steps > 1 else 0
|
|
239
|
+
colors.append(blend_colors(start_color, end_color, ratio))
|
|
240
|
+
return colors
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
# Impact/emphasis colors that work well across palettes
|
|
244
|
+
IMPACT_COLORS = {
|
|
245
|
+
'flash': (255, 255, 240), # Bright flash (cream)
|
|
246
|
+
'explosion': (255, 150, 0), # Orange explosion
|
|
247
|
+
'electricity': (100, 200, 255), # Electric blue
|
|
248
|
+
'fire': (255, 100, 0), # Fire orange-red
|
|
249
|
+
'success': (50, 255, 100), # Success green
|
|
250
|
+
'error': (255, 50, 50), # Error red
|
|
251
|
+
'warning': (255, 200, 0), # Warning yellow
|
|
252
|
+
'magic': (200, 100, 255), # Magic purple
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def get_impact_color(effect_type: str = 'flash') -> tuple[int, int, int]:
|
|
257
|
+
"""
|
|
258
|
+
Get a color for impact/emphasis effects.
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
effect_type: Type of effect (flash, explosion, electricity, etc.)
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
RGB color for effect
|
|
265
|
+
"""
|
|
266
|
+
return IMPACT_COLORS.get(effect_type, IMPACT_COLORS['flash'])
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
# Emoji-safe palettes (work well at 128x128 with 32-64 colors)
|
|
270
|
+
EMOJI_PALETTES = {
|
|
271
|
+
'simple': [
|
|
272
|
+
(255, 255, 255), # White
|
|
273
|
+
(0, 0, 0), # Black
|
|
274
|
+
(255, 100, 100), # Red
|
|
275
|
+
(100, 255, 100), # Green
|
|
276
|
+
(100, 100, 255), # Blue
|
|
277
|
+
(255, 255, 100), # Yellow
|
|
278
|
+
],
|
|
279
|
+
'vibrant_emoji': [
|
|
280
|
+
(255, 255, 255), # White
|
|
281
|
+
(30, 30, 30), # Black
|
|
282
|
+
(255, 68, 68), # Red
|
|
283
|
+
(68, 255, 68), # Green
|
|
284
|
+
(68, 68, 255), # Blue
|
|
285
|
+
(255, 200, 68), # Gold
|
|
286
|
+
(255, 68, 200), # Pink
|
|
287
|
+
(68, 255, 200), # Cyan
|
|
288
|
+
]
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def get_emoji_palette(name: str = 'simple') -> list[tuple[int, int, int]]:
|
|
293
|
+
"""
|
|
294
|
+
Get a limited color palette optimized for emoji GIFs (<64KB).
|
|
295
|
+
|
|
296
|
+
Args:
|
|
297
|
+
name: Palette name (simple, vibrant_emoji)
|
|
298
|
+
|
|
299
|
+
Returns:
|
|
300
|
+
List of RGB colors (6-8 colors)
|
|
301
|
+
"""
|
|
302
|
+
return EMOJI_PALETTES.get(name, EMOJI_PALETTES['simple'])
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Easing Functions - Timing functions for smooth animations.
|
|
4
|
+
|
|
5
|
+
Provides various easing functions for natural motion and timing.
|
|
6
|
+
All functions take a value t (0.0 to 1.0) and return eased value (0.0 to 1.0).
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import math
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def linear(t: float) -> float:
|
|
13
|
+
"""Linear interpolation (no easing)."""
|
|
14
|
+
return t
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def ease_in_quad(t: float) -> float:
|
|
18
|
+
"""Quadratic ease-in (slow start, accelerating)."""
|
|
19
|
+
return t * t
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def ease_out_quad(t: float) -> float:
|
|
23
|
+
"""Quadratic ease-out (fast start, decelerating)."""
|
|
24
|
+
return t * (2 - t)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def ease_in_out_quad(t: float) -> float:
|
|
28
|
+
"""Quadratic ease-in-out (slow start and end)."""
|
|
29
|
+
if t < 0.5:
|
|
30
|
+
return 2 * t * t
|
|
31
|
+
return -1 + (4 - 2 * t) * t
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def ease_in_cubic(t: float) -> float:
|
|
35
|
+
"""Cubic ease-in (slow start)."""
|
|
36
|
+
return t * t * t
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def ease_out_cubic(t: float) -> float:
|
|
40
|
+
"""Cubic ease-out (fast start)."""
|
|
41
|
+
return (t - 1) * (t - 1) * (t - 1) + 1
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def ease_in_out_cubic(t: float) -> float:
|
|
45
|
+
"""Cubic ease-in-out."""
|
|
46
|
+
if t < 0.5:
|
|
47
|
+
return 4 * t * t * t
|
|
48
|
+
return (t - 1) * (2 * t - 2) * (2 * t - 2) + 1
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def ease_in_bounce(t: float) -> float:
|
|
52
|
+
"""Bounce ease-in (bouncy start)."""
|
|
53
|
+
return 1 - ease_out_bounce(1 - t)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def ease_out_bounce(t: float) -> float:
|
|
57
|
+
"""Bounce ease-out (bouncy end)."""
|
|
58
|
+
if t < 1 / 2.75:
|
|
59
|
+
return 7.5625 * t * t
|
|
60
|
+
elif t < 2 / 2.75:
|
|
61
|
+
t -= 1.5 / 2.75
|
|
62
|
+
return 7.5625 * t * t + 0.75
|
|
63
|
+
elif t < 2.5 / 2.75:
|
|
64
|
+
t -= 2.25 / 2.75
|
|
65
|
+
return 7.5625 * t * t + 0.9375
|
|
66
|
+
else:
|
|
67
|
+
t -= 2.625 / 2.75
|
|
68
|
+
return 7.5625 * t * t + 0.984375
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def ease_in_out_bounce(t: float) -> float:
|
|
72
|
+
"""Bounce ease-in-out."""
|
|
73
|
+
if t < 0.5:
|
|
74
|
+
return ease_in_bounce(t * 2) * 0.5
|
|
75
|
+
return ease_out_bounce(t * 2 - 1) * 0.5 + 0.5
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def ease_in_elastic(t: float) -> float:
|
|
79
|
+
"""Elastic ease-in (spring effect)."""
|
|
80
|
+
if t == 0 or t == 1:
|
|
81
|
+
return t
|
|
82
|
+
return -math.pow(2, 10 * (t - 1)) * math.sin((t - 1.1) * 5 * math.pi)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def ease_out_elastic(t: float) -> float:
|
|
86
|
+
"""Elastic ease-out (spring effect)."""
|
|
87
|
+
if t == 0 or t == 1:
|
|
88
|
+
return t
|
|
89
|
+
return math.pow(2, -10 * t) * math.sin((t - 0.1) * 5 * math.pi) + 1
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def ease_in_out_elastic(t: float) -> float:
|
|
93
|
+
"""Elastic ease-in-out."""
|
|
94
|
+
if t == 0 or t == 1:
|
|
95
|
+
return t
|
|
96
|
+
t = t * 2 - 1
|
|
97
|
+
if t < 0:
|
|
98
|
+
return -0.5 * math.pow(2, 10 * t) * math.sin((t - 0.1) * 5 * math.pi)
|
|
99
|
+
return math.pow(2, -10 * t) * math.sin((t - 0.1) * 5 * math.pi) * 0.5 + 1
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
# Convenience mapping
|
|
103
|
+
EASING_FUNCTIONS = {
|
|
104
|
+
'linear': linear,
|
|
105
|
+
'ease_in': ease_in_quad,
|
|
106
|
+
'ease_out': ease_out_quad,
|
|
107
|
+
'ease_in_out': ease_in_out_quad,
|
|
108
|
+
'bounce_in': ease_in_bounce,
|
|
109
|
+
'bounce_out': ease_out_bounce,
|
|
110
|
+
'bounce': ease_in_out_bounce,
|
|
111
|
+
'elastic_in': ease_in_elastic,
|
|
112
|
+
'elastic_out': ease_out_elastic,
|
|
113
|
+
'elastic': ease_in_out_elastic,
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def get_easing(name: str = 'linear'):
|
|
118
|
+
"""Get easing function by name."""
|
|
119
|
+
return EASING_FUNCTIONS.get(name, linear)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def interpolate(start: float, end: float, t: float, easing: str = 'linear') -> float:
|
|
123
|
+
"""
|
|
124
|
+
Interpolate between two values with easing.
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
start: Start value
|
|
128
|
+
end: End value
|
|
129
|
+
t: Progress from 0.0 to 1.0
|
|
130
|
+
easing: Name of easing function
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
Interpolated value
|
|
134
|
+
"""
|
|
135
|
+
ease_func = get_easing(easing)
|
|
136
|
+
eased_t = ease_func(t)
|
|
137
|
+
return start + (end - start) * eased_t
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def ease_back_in(t: float) -> float:
|
|
141
|
+
"""Back ease-in (slight overshoot backward before forward motion)."""
|
|
142
|
+
c1 = 1.70158
|
|
143
|
+
c3 = c1 + 1
|
|
144
|
+
return c3 * t * t * t - c1 * t * t
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def ease_back_out(t: float) -> float:
|
|
148
|
+
"""Back ease-out (overshoot forward then settle back)."""
|
|
149
|
+
c1 = 1.70158
|
|
150
|
+
c3 = c1 + 1
|
|
151
|
+
return 1 + c3 * pow(t - 1, 3) + c1 * pow(t - 1, 2)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def ease_back_in_out(t: float) -> float:
|
|
155
|
+
"""Back ease-in-out (overshoot at both ends)."""
|
|
156
|
+
c1 = 1.70158
|
|
157
|
+
c2 = c1 * 1.525
|
|
158
|
+
if t < 0.5:
|
|
159
|
+
return (pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2)) / 2
|
|
160
|
+
return (pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def apply_squash_stretch(base_scale: tuple[float, float], intensity: float,
|
|
164
|
+
direction: str = 'vertical') -> tuple[float, float]:
|
|
165
|
+
"""
|
|
166
|
+
Calculate squash and stretch scales for more dynamic animation.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
base_scale: (width_scale, height_scale) base scales
|
|
170
|
+
intensity: Squash/stretch intensity (0.0-1.0)
|
|
171
|
+
direction: 'vertical', 'horizontal', or 'both'
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
(width_scale, height_scale) with squash/stretch applied
|
|
175
|
+
"""
|
|
176
|
+
width_scale, height_scale = base_scale
|
|
177
|
+
|
|
178
|
+
if direction == 'vertical':
|
|
179
|
+
# Compress vertically, expand horizontally (preserve volume)
|
|
180
|
+
height_scale *= (1 - intensity * 0.5)
|
|
181
|
+
width_scale *= (1 + intensity * 0.5)
|
|
182
|
+
elif direction == 'horizontal':
|
|
183
|
+
# Compress horizontally, expand vertically
|
|
184
|
+
width_scale *= (1 - intensity * 0.5)
|
|
185
|
+
height_scale *= (1 + intensity * 0.5)
|
|
186
|
+
elif direction == 'both':
|
|
187
|
+
# General squash (both dimensions)
|
|
188
|
+
width_scale *= (1 - intensity * 0.3)
|
|
189
|
+
height_scale *= (1 - intensity * 0.3)
|
|
190
|
+
|
|
191
|
+
return (width_scale, height_scale)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def calculate_arc_motion(start: tuple[float, float], end: tuple[float, float],
|
|
195
|
+
height: float, t: float) -> tuple[float, float]:
|
|
196
|
+
"""
|
|
197
|
+
Calculate position along a parabolic arc (natural motion path).
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
start: (x, y) starting position
|
|
201
|
+
end: (x, y) ending position
|
|
202
|
+
height: Arc height at midpoint (positive = upward)
|
|
203
|
+
t: Progress (0.0-1.0)
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
(x, y) position along arc
|
|
207
|
+
"""
|
|
208
|
+
x1, y1 = start
|
|
209
|
+
x2, y2 = end
|
|
210
|
+
|
|
211
|
+
# Linear interpolation for x
|
|
212
|
+
x = x1 + (x2 - x1) * t
|
|
213
|
+
|
|
214
|
+
# Parabolic interpolation for y
|
|
215
|
+
# y = start + progress * (end - start) + arc_offset
|
|
216
|
+
# Arc offset peaks at t=0.5
|
|
217
|
+
arc_offset = 4 * height * t * (1 - t)
|
|
218
|
+
y = y1 + (y2 - y1) * t - arc_offset
|
|
219
|
+
|
|
220
|
+
return (x, y)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
# Add new easing functions to the convenience mapping
|
|
224
|
+
EASING_FUNCTIONS.update({
|
|
225
|
+
'back_in': ease_back_in,
|
|
226
|
+
'back_out': ease_back_out,
|
|
227
|
+
'back_in_out': ease_back_in_out,
|
|
228
|
+
'anticipate': ease_back_in, # Alias
|
|
229
|
+
'overshoot': ease_back_out, # Alias
|
|
230
|
+
})
|