@papert-code/papert-code 0.3.94 → 0.3.96
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/README.md +21 -0
- package/dist/chunks/{chunk-OIA427PZ.js → chunk-HSYOWGEB.js} +1 -1
- package/dist/chunks/{chunk-6ZOXSA5F.js → chunk-IK4ISYCE.js} +4 -4
- package/dist/chunks/{chunk-JATIVKZP.js → chunk-KBPFDUTA.js} +55 -10
- package/dist/chunks/{chunk-7T4OCWHU.js → chunk-TNDQXJLA.js} +1931 -787
- package/dist/chunks/{gemini-WYRXV2QC.js → gemini-MVJNXCFF.js} +20547 -16879
- package/dist/chunks/{openaiContentGenerator-EAVO6L3Y.js → openaiContentGenerator-GTG5MK5E.js} +2 -2
- package/dist/chunks/{papertContentGenerator-G4SBF3DR.js → papertContentGenerator-Q5TTXUE6.js} +3 -3
- package/dist/chunks/{server-N2U4FF55.js → server-6D3KYATG.js} +7 -1
- package/dist/cli.js +5 -4
- package/dist/sandbox-macos-permissive-proxied.sb +1 -1
- package/dist/sandbox-macos-restrictive-proxied.sb +1 -1
- package/dist/skills/algorithmic-art/SKILL.md +405 -0
- package/dist/skills/algorithmic-art/templates/generator_template.js +223 -0
- package/dist/skills/algorithmic-art/templates/viewer.html +599 -0
- package/dist/skills/brand-guidelines/SKILL.md +73 -0
- package/dist/skills/canvas-design/SKILL.md +130 -0
- package/dist/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/dist/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/dist/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/dist/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/dist/skills/doc-coauthoring/SKILL.md +375 -0
- package/dist/skills/docx/SKILL.md +481 -0
- package/dist/skills/docx/scripts/__init__.py +1 -0
- package/dist/skills/docx/scripts/accept_changes.py +135 -0
- package/dist/skills/docx/scripts/comment.py +318 -0
- package/dist/skills/docx/scripts/office/helpers/__init__.py +0 -0
- package/dist/skills/docx/scripts/office/helpers/merge_runs.py +199 -0
- package/dist/skills/docx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/dist/skills/docx/scripts/office/pack.py +159 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/dist/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/dist/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/dist/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/dist/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/dist/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/dist/skills/docx/scripts/office/schemas/mce/mc.xsd +75 -0
- package/dist/skills/docx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/dist/skills/docx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/dist/skills/docx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/dist/skills/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/dist/skills/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/dist/skills/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/dist/skills/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/dist/skills/docx/scripts/office/soffice.py +183 -0
- package/dist/skills/docx/scripts/office/unpack.py +132 -0
- package/dist/skills/docx/scripts/office/validate.py +111 -0
- package/dist/skills/docx/scripts/office/validators/__init__.py +15 -0
- package/dist/skills/docx/scripts/office/validators/base.py +847 -0
- package/dist/skills/docx/scripts/office/validators/docx.py +446 -0
- package/dist/skills/docx/scripts/office/validators/pptx.py +275 -0
- package/dist/skills/docx/scripts/office/validators/redlining.py +247 -0
- package/dist/skills/docx/scripts/templates/comments.xml +3 -0
- package/dist/skills/docx/scripts/templates/commentsExtended.xml +3 -0
- package/dist/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/dist/skills/docx/scripts/templates/commentsIds.xml +3 -0
- package/dist/skills/docx/scripts/templates/people.xml +3 -0
- package/dist/skills/frontend-design/SKILL.md +42 -0
- package/dist/skills/internal-comms/SKILL.md +32 -0
- package/dist/skills/internal-comms/examples/3p-updates.md +47 -0
- package/dist/skills/internal-comms/examples/company-newsletter.md +65 -0
- package/dist/skills/internal-comms/examples/faq-answers.md +30 -0
- package/dist/skills/internal-comms/examples/general-comms.md +16 -0
- package/dist/skills/mcp-builder/SKILL.md +236 -0
- package/dist/skills/mcp-builder/reference/evaluation.md +602 -0
- package/dist/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
- package/dist/skills/mcp-builder/reference/node_mcp_server.md +970 -0
- package/dist/skills/mcp-builder/reference/python_mcp_server.md +719 -0
- package/dist/skills/mcp-builder/scripts/connections.py +151 -0
- package/dist/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/dist/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/dist/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/dist/skills/papert-code/SKILL.md +561 -0
- package/dist/skills/pdf/SKILL.md +314 -0
- package/dist/skills/pdf/forms.md +294 -0
- package/dist/skills/pdf/reference.md +612 -0
- package/dist/skills/pdf/scripts/check_bounding_boxes.py +65 -0
- package/dist/skills/pdf/scripts/check_fillable_fields.py +11 -0
- package/dist/skills/pdf/scripts/convert_pdf_to_images.py +33 -0
- package/dist/skills/pdf/scripts/create_validation_image.py +37 -0
- package/dist/skills/pdf/scripts/extract_form_field_info.py +122 -0
- package/dist/skills/pdf/scripts/extract_form_structure.py +115 -0
- package/dist/skills/pdf/scripts/fill_fillable_fields.py +98 -0
- package/dist/skills/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
- package/dist/skills/pptx/SKILL.md +232 -0
- package/dist/skills/pptx/editing.md +205 -0
- package/dist/skills/pptx/pptxgenjs.md +420 -0
- package/dist/skills/pptx/scripts/__init__.py +0 -0
- package/dist/skills/pptx/scripts/add_slide.py +195 -0
- package/dist/skills/pptx/scripts/clean.py +286 -0
- package/dist/skills/pptx/scripts/office/helpers/__init__.py +0 -0
- package/dist/skills/pptx/scripts/office/helpers/merge_runs.py +199 -0
- package/dist/skills/pptx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/dist/skills/pptx/scripts/office/pack.py +159 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/dist/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/dist/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/dist/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/dist/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/dist/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/dist/skills/pptx/scripts/office/schemas/mce/mc.xsd +75 -0
- package/dist/skills/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/dist/skills/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/dist/skills/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/dist/skills/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/dist/skills/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/dist/skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/dist/skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/dist/skills/pptx/scripts/office/soffice.py +183 -0
- package/dist/skills/pptx/scripts/office/unpack.py +132 -0
- package/dist/skills/pptx/scripts/office/validate.py +111 -0
- package/dist/skills/pptx/scripts/office/validators/__init__.py +15 -0
- package/dist/skills/pptx/scripts/office/validators/base.py +847 -0
- package/dist/skills/pptx/scripts/office/validators/docx.py +446 -0
- package/dist/skills/pptx/scripts/office/validators/pptx.py +275 -0
- package/dist/skills/pptx/scripts/office/validators/redlining.py +247 -0
- package/dist/skills/pptx/scripts/thumbnail.py +289 -0
- package/dist/skills/skill-creator/SKILL.md +357 -0
- package/dist/skills/skill-creator/references/output-patterns.md +82 -0
- package/dist/skills/skill-creator/references/workflows.md +28 -0
- package/dist/skills/skill-creator/scripts/init_skill.py +303 -0
- package/dist/skills/skill-creator/scripts/package_skill.py +110 -0
- package/dist/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/dist/skills/slack-gif-creator/SKILL.md +254 -0
- package/dist/skills/slack-gif-creator/core/easing.py +234 -0
- package/dist/skills/slack-gif-creator/core/frame_composer.py +176 -0
- package/dist/skills/slack-gif-creator/core/gif_builder.py +269 -0
- package/dist/skills/slack-gif-creator/core/validators.py +136 -0
- package/dist/skills/slack-gif-creator/requirements.txt +4 -0
- package/dist/skills/theme-factory/SKILL.md +59 -0
- package/dist/skills/theme-factory/theme-showcase.pdf +0 -0
- package/dist/skills/theme-factory/themes/arctic-frost.md +19 -0
- package/dist/skills/theme-factory/themes/botanical-garden.md +19 -0
- package/dist/skills/theme-factory/themes/desert-rose.md +19 -0
- package/dist/skills/theme-factory/themes/forest-canopy.md +19 -0
- package/dist/skills/theme-factory/themes/golden-hour.md +19 -0
- package/dist/skills/theme-factory/themes/midnight-galaxy.md +19 -0
- package/dist/skills/theme-factory/themes/modern-minimalist.md +19 -0
- package/dist/skills/theme-factory/themes/ocean-depths.md +19 -0
- package/dist/skills/theme-factory/themes/sunset-boulevard.md +19 -0
- package/dist/skills/theme-factory/themes/tech-innovation.md +19 -0
- package/dist/skills/web-artifacts-builder/SKILL.md +74 -0
- package/dist/skills/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/dist/skills/web-artifacts-builder/scripts/init-artifact.sh +322 -0
- package/dist/skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/dist/skills/webapp-testing/SKILL.md +96 -0
- package/dist/skills/webapp-testing/examples/console_logging.py +35 -0
- package/dist/skills/webapp-testing/examples/element_discovery.py +40 -0
- package/dist/skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/dist/skills/webapp-testing/scripts/with_server.py +106 -0
- package/dist/skills/xlsx/SKILL.md +292 -0
- package/dist/skills/xlsx/scripts/office/helpers/__init__.py +0 -0
- package/dist/skills/xlsx/scripts/office/helpers/merge_runs.py +199 -0
- package/dist/skills/xlsx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/dist/skills/xlsx/scripts/office/pack.py +159 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/dist/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/dist/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/dist/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/dist/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/dist/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/dist/skills/xlsx/scripts/office/schemas/mce/mc.xsd +75 -0
- package/dist/skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/dist/skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/dist/skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/dist/skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/dist/skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/dist/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/dist/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/dist/skills/xlsx/scripts/office/soffice.py +183 -0
- package/dist/skills/xlsx/scripts/office/unpack.py +132 -0
- package/dist/skills/xlsx/scripts/office/validate.py +111 -0
- package/dist/skills/xlsx/scripts/office/validators/__init__.py +15 -0
- package/dist/skills/xlsx/scripts/office/validators/base.py +847 -0
- package/dist/skills/xlsx/scripts/office/validators/docx.py +446 -0
- package/dist/skills/xlsx/scripts/office/validators/pptx.py +275 -0
- package/dist/skills/xlsx/scripts/office/validators/redlining.py +247 -0
- package/dist/skills/xlsx/scripts/recalc.py +184 -0
- package/package.json +11 -4
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: slack-gif-creator
|
|
3
|
+
description: Knowledge and utilities for creating animated GIFs optimized for Slack. Provides constraints, validation tools, and animation concepts. Use when users request animated GIFs for Slack like "make me a GIF of X doing Y for Slack."
|
|
4
|
+
license: Complete terms in LICENSE.txt
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Slack GIF Creator
|
|
8
|
+
|
|
9
|
+
A toolkit providing utilities and knowledge for creating animated GIFs optimized for Slack.
|
|
10
|
+
|
|
11
|
+
## Slack Requirements
|
|
12
|
+
|
|
13
|
+
**Dimensions:**
|
|
14
|
+
- Emoji GIFs: 128x128 (recommended)
|
|
15
|
+
- Message GIFs: 480x480
|
|
16
|
+
|
|
17
|
+
**Parameters:**
|
|
18
|
+
- FPS: 10-30 (lower is smaller file size)
|
|
19
|
+
- Colors: 48-128 (fewer = smaller file size)
|
|
20
|
+
- Duration: Keep under 3 seconds for emoji GIFs
|
|
21
|
+
|
|
22
|
+
## Core Workflow
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
from core.gif_builder import GIFBuilder
|
|
26
|
+
from PIL import Image, ImageDraw
|
|
27
|
+
|
|
28
|
+
# 1. Create builder
|
|
29
|
+
builder = GIFBuilder(width=128, height=128, fps=10)
|
|
30
|
+
|
|
31
|
+
# 2. Generate frames
|
|
32
|
+
for i in range(12):
|
|
33
|
+
frame = Image.new('RGB', (128, 128), (240, 248, 255))
|
|
34
|
+
draw = ImageDraw.Draw(frame)
|
|
35
|
+
|
|
36
|
+
# Draw your animation using PIL primitives
|
|
37
|
+
# (circles, polygons, lines, etc.)
|
|
38
|
+
|
|
39
|
+
builder.add_frame(frame)
|
|
40
|
+
|
|
41
|
+
# 3. Save with optimization
|
|
42
|
+
builder.save('output.gif', num_colors=48, optimize_for_emoji=True)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Drawing Graphics
|
|
46
|
+
|
|
47
|
+
### Working with User-Uploaded Images
|
|
48
|
+
If a user uploads an image, consider whether they want to:
|
|
49
|
+
- **Use it directly** (e.g., "animate this", "split this into frames")
|
|
50
|
+
- **Use it as inspiration** (e.g., "make something like this")
|
|
51
|
+
|
|
52
|
+
Load and work with images using PIL:
|
|
53
|
+
```python
|
|
54
|
+
from PIL import Image
|
|
55
|
+
|
|
56
|
+
uploaded = Image.open('file.png')
|
|
57
|
+
# Use directly, or just as reference for colors/style
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Drawing from Scratch
|
|
61
|
+
When drawing graphics from scratch, use PIL ImageDraw primitives:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from PIL import ImageDraw
|
|
65
|
+
|
|
66
|
+
draw = ImageDraw.Draw(frame)
|
|
67
|
+
|
|
68
|
+
# Circles/ovals
|
|
69
|
+
draw.ellipse([x1, y1, x2, y2], fill=(r, g, b), outline=(r, g, b), width=3)
|
|
70
|
+
|
|
71
|
+
# Stars, triangles, any polygon
|
|
72
|
+
points = [(x1, y1), (x2, y2), (x3, y3), ...]
|
|
73
|
+
draw.polygon(points, fill=(r, g, b), outline=(r, g, b), width=3)
|
|
74
|
+
|
|
75
|
+
# Lines
|
|
76
|
+
draw.line([(x1, y1), (x2, y2)], fill=(r, g, b), width=5)
|
|
77
|
+
|
|
78
|
+
# Rectangles
|
|
79
|
+
draw.rectangle([x1, y1, x2, y2], fill=(r, g, b), outline=(r, g, b), width=3)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Don't use:** Emoji fonts (unreliable across platforms) or assume pre-packaged graphics exist in this skill.
|
|
83
|
+
|
|
84
|
+
### Making Graphics Look Good
|
|
85
|
+
|
|
86
|
+
Graphics should look polished and creative, not basic. Here's how:
|
|
87
|
+
|
|
88
|
+
**Use thicker lines** - Always set `width=2` or higher for outlines and lines. Thin lines (width=1) look choppy and amateurish.
|
|
89
|
+
|
|
90
|
+
**Add visual depth**:
|
|
91
|
+
- Use gradients for backgrounds (`create_gradient_background`)
|
|
92
|
+
- Layer multiple shapes for complexity (e.g., a star with a smaller star inside)
|
|
93
|
+
|
|
94
|
+
**Make shapes more interesting**:
|
|
95
|
+
- Don't just draw a plain circle - add highlights, rings, or patterns
|
|
96
|
+
- Stars can have glows (draw larger, semi-transparent versions behind)
|
|
97
|
+
- Combine multiple shapes (stars + sparkles, circles + rings)
|
|
98
|
+
|
|
99
|
+
**Pay attention to colors**:
|
|
100
|
+
- Use vibrant, complementary colors
|
|
101
|
+
- Add contrast (dark outlines on light shapes, light outlines on dark shapes)
|
|
102
|
+
- Consider the overall composition
|
|
103
|
+
|
|
104
|
+
**For complex shapes** (hearts, snowflakes, etc.):
|
|
105
|
+
- Use combinations of polygons and ellipses
|
|
106
|
+
- Calculate points carefully for symmetry
|
|
107
|
+
- Add details (a heart can have a highlight curve, snowflakes have intricate branches)
|
|
108
|
+
|
|
109
|
+
Be creative and detailed! A good Slack GIF should look polished, not like placeholder graphics.
|
|
110
|
+
|
|
111
|
+
## Available Utilities
|
|
112
|
+
|
|
113
|
+
### GIFBuilder (`core.gif_builder`)
|
|
114
|
+
Assembles frames and optimizes for Slack:
|
|
115
|
+
```python
|
|
116
|
+
builder = GIFBuilder(width=128, height=128, fps=10)
|
|
117
|
+
builder.add_frame(frame) # Add PIL Image
|
|
118
|
+
builder.add_frames(frames) # Add list of frames
|
|
119
|
+
builder.save('out.gif', num_colors=48, optimize_for_emoji=True, remove_duplicates=True)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Validators (`core.validators`)
|
|
123
|
+
Check if GIF meets Slack requirements:
|
|
124
|
+
```python
|
|
125
|
+
from core.validators import validate_gif, is_slack_ready
|
|
126
|
+
|
|
127
|
+
# Detailed validation
|
|
128
|
+
passes, info = validate_gif('my.gif', is_emoji=True, verbose=True)
|
|
129
|
+
|
|
130
|
+
# Quick check
|
|
131
|
+
if is_slack_ready('my.gif'):
|
|
132
|
+
print("Ready!")
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Easing Functions (`core.easing`)
|
|
136
|
+
Smooth motion instead of linear:
|
|
137
|
+
```python
|
|
138
|
+
from core.easing import interpolate
|
|
139
|
+
|
|
140
|
+
# Progress from 0.0 to 1.0
|
|
141
|
+
t = i / (num_frames - 1)
|
|
142
|
+
|
|
143
|
+
# Apply easing
|
|
144
|
+
y = interpolate(start=0, end=400, t=t, easing='ease_out')
|
|
145
|
+
|
|
146
|
+
# Available: linear, ease_in, ease_out, ease_in_out,
|
|
147
|
+
# bounce_out, elastic_out, back_out
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Frame Helpers (`core.frame_composer`)
|
|
151
|
+
Convenience functions for common needs:
|
|
152
|
+
```python
|
|
153
|
+
from core.frame_composer import (
|
|
154
|
+
create_blank_frame, # Solid color background
|
|
155
|
+
create_gradient_background, # Vertical gradient
|
|
156
|
+
draw_circle, # Helper for circles
|
|
157
|
+
draw_text, # Simple text rendering
|
|
158
|
+
draw_star # 5-pointed star
|
|
159
|
+
)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Animation Concepts
|
|
163
|
+
|
|
164
|
+
### Shake/Vibrate
|
|
165
|
+
Offset object position with oscillation:
|
|
166
|
+
- Use `math.sin()` or `math.cos()` with frame index
|
|
167
|
+
- Add small random variations for natural feel
|
|
168
|
+
- Apply to x and/or y position
|
|
169
|
+
|
|
170
|
+
### Pulse/Heartbeat
|
|
171
|
+
Scale object size rhythmically:
|
|
172
|
+
- Use `math.sin(t * frequency * 2 * math.pi)` for smooth pulse
|
|
173
|
+
- For heartbeat: two quick pulses then pause (adjust sine wave)
|
|
174
|
+
- Scale between 0.8 and 1.2 of base size
|
|
175
|
+
|
|
176
|
+
### Bounce
|
|
177
|
+
Object falls and bounces:
|
|
178
|
+
- Use `interpolate()` with `easing='bounce_out'` for landing
|
|
179
|
+
- Use `easing='ease_in'` for falling (accelerating)
|
|
180
|
+
- Apply gravity by increasing y velocity each frame
|
|
181
|
+
|
|
182
|
+
### Spin/Rotate
|
|
183
|
+
Rotate object around center:
|
|
184
|
+
- PIL: `image.rotate(angle, resample=Image.BICUBIC)`
|
|
185
|
+
- For wobble: use sine wave for angle instead of linear
|
|
186
|
+
|
|
187
|
+
### Fade In/Out
|
|
188
|
+
Gradually appear or disappear:
|
|
189
|
+
- Create RGBA image, adjust alpha channel
|
|
190
|
+
- Or use `Image.blend(image1, image2, alpha)`
|
|
191
|
+
- Fade in: alpha from 0 to 1
|
|
192
|
+
- Fade out: alpha from 1 to 0
|
|
193
|
+
|
|
194
|
+
### Slide
|
|
195
|
+
Move object from off-screen to position:
|
|
196
|
+
- Start position: outside frame bounds
|
|
197
|
+
- End position: target location
|
|
198
|
+
- Use `interpolate()` with `easing='ease_out'` for smooth stop
|
|
199
|
+
- For overshoot: use `easing='back_out'`
|
|
200
|
+
|
|
201
|
+
### Zoom
|
|
202
|
+
Scale and position for zoom effect:
|
|
203
|
+
- Zoom in: scale from 0.1 to 2.0, crop center
|
|
204
|
+
- Zoom out: scale from 2.0 to 1.0
|
|
205
|
+
- Can add motion blur for drama (PIL filter)
|
|
206
|
+
|
|
207
|
+
### Explode/Particle Burst
|
|
208
|
+
Create particles radiating outward:
|
|
209
|
+
- Generate particles with random angles and velocities
|
|
210
|
+
- Update each particle: `x += vx`, `y += vy`
|
|
211
|
+
- Add gravity: `vy += gravity_constant`
|
|
212
|
+
- Fade out particles over time (reduce alpha)
|
|
213
|
+
|
|
214
|
+
## Optimization Strategies
|
|
215
|
+
|
|
216
|
+
Only when asked to make the file size smaller, implement a few of the following methods:
|
|
217
|
+
|
|
218
|
+
1. **Fewer frames** - Lower FPS (10 instead of 20) or shorter duration
|
|
219
|
+
2. **Fewer colors** - `num_colors=48` instead of 128
|
|
220
|
+
3. **Smaller dimensions** - 128x128 instead of 480x480
|
|
221
|
+
4. **Remove duplicates** - `remove_duplicates=True` in save()
|
|
222
|
+
5. **Emoji mode** - `optimize_for_emoji=True` auto-optimizes
|
|
223
|
+
|
|
224
|
+
```python
|
|
225
|
+
# Maximum optimization for emoji
|
|
226
|
+
builder.save(
|
|
227
|
+
'emoji.gif',
|
|
228
|
+
num_colors=48,
|
|
229
|
+
optimize_for_emoji=True,
|
|
230
|
+
remove_duplicates=True
|
|
231
|
+
)
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Philosophy
|
|
235
|
+
|
|
236
|
+
This skill provides:
|
|
237
|
+
- **Knowledge**: Slack's requirements and animation concepts
|
|
238
|
+
- **Utilities**: GIFBuilder, validators, easing functions
|
|
239
|
+
- **Flexibility**: Create the animation logic using PIL primitives
|
|
240
|
+
|
|
241
|
+
It does NOT provide:
|
|
242
|
+
- Rigid animation templates or pre-made functions
|
|
243
|
+
- Emoji font rendering (unreliable across platforms)
|
|
244
|
+
- A library of pre-packaged graphics built into the skill
|
|
245
|
+
|
|
246
|
+
**Note on user uploads**: This skill doesn't include pre-built graphics, but if a user uploads an image, use PIL to load and work with it - interpret based on their request whether they want it used directly or just as inspiration.
|
|
247
|
+
|
|
248
|
+
Be creative! Combine concepts (bouncing + rotating, pulsing + sliding, etc.) and use PIL's full capabilities.
|
|
249
|
+
|
|
250
|
+
## Dependencies
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
pip install pillow imageio numpy
|
|
254
|
+
```
|
|
@@ -0,0 +1,234 @@
|
|
|
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(
|
|
164
|
+
base_scale: tuple[float, float], intensity: float, direction: str = "vertical"
|
|
165
|
+
) -> tuple[float, float]:
|
|
166
|
+
"""
|
|
167
|
+
Calculate squash and stretch scales for more dynamic animation.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
base_scale: (width_scale, height_scale) base scales
|
|
171
|
+
intensity: Squash/stretch intensity (0.0-1.0)
|
|
172
|
+
direction: 'vertical', 'horizontal', or 'both'
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
(width_scale, height_scale) with squash/stretch applied
|
|
176
|
+
"""
|
|
177
|
+
width_scale, height_scale = base_scale
|
|
178
|
+
|
|
179
|
+
if direction == "vertical":
|
|
180
|
+
# Compress vertically, expand horizontally (preserve volume)
|
|
181
|
+
height_scale *= 1 - intensity * 0.5
|
|
182
|
+
width_scale *= 1 + intensity * 0.5
|
|
183
|
+
elif direction == "horizontal":
|
|
184
|
+
# Compress horizontally, expand vertically
|
|
185
|
+
width_scale *= 1 - intensity * 0.5
|
|
186
|
+
height_scale *= 1 + intensity * 0.5
|
|
187
|
+
elif direction == "both":
|
|
188
|
+
# General squash (both dimensions)
|
|
189
|
+
width_scale *= 1 - intensity * 0.3
|
|
190
|
+
height_scale *= 1 - intensity * 0.3
|
|
191
|
+
|
|
192
|
+
return (width_scale, height_scale)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def calculate_arc_motion(
|
|
196
|
+
start: tuple[float, float], end: tuple[float, float], height: float, t: float
|
|
197
|
+
) -> tuple[float, float]:
|
|
198
|
+
"""
|
|
199
|
+
Calculate position along a parabolic arc (natural motion path).
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
start: (x, y) starting position
|
|
203
|
+
end: (x, y) ending position
|
|
204
|
+
height: Arc height at midpoint (positive = upward)
|
|
205
|
+
t: Progress (0.0-1.0)
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
(x, y) position along arc
|
|
209
|
+
"""
|
|
210
|
+
x1, y1 = start
|
|
211
|
+
x2, y2 = end
|
|
212
|
+
|
|
213
|
+
# Linear interpolation for x
|
|
214
|
+
x = x1 + (x2 - x1) * t
|
|
215
|
+
|
|
216
|
+
# Parabolic interpolation for y
|
|
217
|
+
# y = start + progress * (end - start) + arc_offset
|
|
218
|
+
# Arc offset peaks at t=0.5
|
|
219
|
+
arc_offset = 4 * height * t * (1 - t)
|
|
220
|
+
y = y1 + (y2 - y1) * t - arc_offset
|
|
221
|
+
|
|
222
|
+
return (x, y)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
# Add new easing functions to the convenience mapping
|
|
226
|
+
EASING_FUNCTIONS.update(
|
|
227
|
+
{
|
|
228
|
+
"back_in": ease_back_in,
|
|
229
|
+
"back_out": ease_back_out,
|
|
230
|
+
"back_in_out": ease_back_in_out,
|
|
231
|
+
"anticipate": ease_back_in, # Alias
|
|
232
|
+
"overshoot": ease_back_out, # Alias
|
|
233
|
+
}
|
|
234
|
+
)
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Frame Composer - Utilities for composing visual elements into frames.
|
|
4
|
+
|
|
5
|
+
Provides functions for drawing shapes, text, emojis, and compositing elements
|
|
6
|
+
together to create animation frames.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Optional
|
|
10
|
+
|
|
11
|
+
import numpy as np
|
|
12
|
+
from PIL import Image, ImageDraw, ImageFont
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def create_blank_frame(
|
|
16
|
+
width: int, height: int, color: tuple[int, int, int] = (255, 255, 255)
|
|
17
|
+
) -> Image.Image:
|
|
18
|
+
"""
|
|
19
|
+
Create a blank frame with solid color background.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
width: Frame width
|
|
23
|
+
height: Frame height
|
|
24
|
+
color: RGB color tuple (default: white)
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
PIL Image
|
|
28
|
+
"""
|
|
29
|
+
return Image.new("RGB", (width, height), color)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def draw_circle(
|
|
33
|
+
frame: Image.Image,
|
|
34
|
+
center: tuple[int, int],
|
|
35
|
+
radius: int,
|
|
36
|
+
fill_color: Optional[tuple[int, int, int]] = None,
|
|
37
|
+
outline_color: Optional[tuple[int, int, int]] = None,
|
|
38
|
+
outline_width: int = 1,
|
|
39
|
+
) -> Image.Image:
|
|
40
|
+
"""
|
|
41
|
+
Draw a circle on a frame.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
frame: PIL Image to draw on
|
|
45
|
+
center: (x, y) center position
|
|
46
|
+
radius: Circle radius
|
|
47
|
+
fill_color: RGB fill color (None for no fill)
|
|
48
|
+
outline_color: RGB outline color (None for no outline)
|
|
49
|
+
outline_width: Outline width in pixels
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Modified frame
|
|
53
|
+
"""
|
|
54
|
+
draw = ImageDraw.Draw(frame)
|
|
55
|
+
x, y = center
|
|
56
|
+
bbox = [x - radius, y - radius, x + radius, y + radius]
|
|
57
|
+
draw.ellipse(bbox, fill=fill_color, outline=outline_color, width=outline_width)
|
|
58
|
+
return frame
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def draw_text(
|
|
62
|
+
frame: Image.Image,
|
|
63
|
+
text: str,
|
|
64
|
+
position: tuple[int, int],
|
|
65
|
+
color: tuple[int, int, int] = (0, 0, 0),
|
|
66
|
+
centered: bool = False,
|
|
67
|
+
) -> Image.Image:
|
|
68
|
+
"""
|
|
69
|
+
Draw text on a frame.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
frame: PIL Image to draw on
|
|
73
|
+
text: Text to draw
|
|
74
|
+
position: (x, y) position (top-left unless centered=True)
|
|
75
|
+
color: RGB text color
|
|
76
|
+
centered: If True, center text at position
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
Modified frame
|
|
80
|
+
"""
|
|
81
|
+
draw = ImageDraw.Draw(frame)
|
|
82
|
+
|
|
83
|
+
# Uses Pillow's default font.
|
|
84
|
+
# If the font should be changed for the emoji, add additional logic here.
|
|
85
|
+
font = ImageFont.load_default()
|
|
86
|
+
|
|
87
|
+
if centered:
|
|
88
|
+
bbox = draw.textbbox((0, 0), text, font=font)
|
|
89
|
+
text_width = bbox[2] - bbox[0]
|
|
90
|
+
text_height = bbox[3] - bbox[1]
|
|
91
|
+
x = position[0] - text_width // 2
|
|
92
|
+
y = position[1] - text_height // 2
|
|
93
|
+
position = (x, y)
|
|
94
|
+
|
|
95
|
+
draw.text(position, text, fill=color, font=font)
|
|
96
|
+
return frame
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def create_gradient_background(
|
|
100
|
+
width: int,
|
|
101
|
+
height: int,
|
|
102
|
+
top_color: tuple[int, int, int],
|
|
103
|
+
bottom_color: tuple[int, int, int],
|
|
104
|
+
) -> Image.Image:
|
|
105
|
+
"""
|
|
106
|
+
Create a vertical gradient background.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
width: Frame width
|
|
110
|
+
height: Frame height
|
|
111
|
+
top_color: RGB color at top
|
|
112
|
+
bottom_color: RGB color at bottom
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
PIL Image with gradient
|
|
116
|
+
"""
|
|
117
|
+
frame = Image.new("RGB", (width, height))
|
|
118
|
+
draw = ImageDraw.Draw(frame)
|
|
119
|
+
|
|
120
|
+
# Calculate color step for each row
|
|
121
|
+
r1, g1, b1 = top_color
|
|
122
|
+
r2, g2, b2 = bottom_color
|
|
123
|
+
|
|
124
|
+
for y in range(height):
|
|
125
|
+
# Interpolate color
|
|
126
|
+
ratio = y / height
|
|
127
|
+
r = int(r1 * (1 - ratio) + r2 * ratio)
|
|
128
|
+
g = int(g1 * (1 - ratio) + g2 * ratio)
|
|
129
|
+
b = int(b1 * (1 - ratio) + b2 * ratio)
|
|
130
|
+
|
|
131
|
+
# Draw horizontal line
|
|
132
|
+
draw.line([(0, y), (width, y)], fill=(r, g, b))
|
|
133
|
+
|
|
134
|
+
return frame
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def draw_star(
|
|
138
|
+
frame: Image.Image,
|
|
139
|
+
center: tuple[int, int],
|
|
140
|
+
size: int,
|
|
141
|
+
fill_color: tuple[int, int, int],
|
|
142
|
+
outline_color: Optional[tuple[int, int, int]] = None,
|
|
143
|
+
outline_width: int = 1,
|
|
144
|
+
) -> Image.Image:
|
|
145
|
+
"""
|
|
146
|
+
Draw a 5-pointed star.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
frame: PIL Image to draw on
|
|
150
|
+
center: (x, y) center position
|
|
151
|
+
size: Star size (outer radius)
|
|
152
|
+
fill_color: RGB fill color
|
|
153
|
+
outline_color: RGB outline color (None for no outline)
|
|
154
|
+
outline_width: Outline width
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
Modified frame
|
|
158
|
+
"""
|
|
159
|
+
import math
|
|
160
|
+
|
|
161
|
+
draw = ImageDraw.Draw(frame)
|
|
162
|
+
x, y = center
|
|
163
|
+
|
|
164
|
+
# Calculate star points
|
|
165
|
+
points = []
|
|
166
|
+
for i in range(10):
|
|
167
|
+
angle = (i * 36 - 90) * math.pi / 180 # 36 degrees per point, start at top
|
|
168
|
+
radius = size if i % 2 == 0 else size * 0.4 # Alternate between outer and inner
|
|
169
|
+
px = x + radius * math.cos(angle)
|
|
170
|
+
py = y + radius * math.sin(angle)
|
|
171
|
+
points.append((px, py))
|
|
172
|
+
|
|
173
|
+
# Draw star
|
|
174
|
+
draw.polygon(points, fill=fill_color, outline=outline_color, width=outline_width)
|
|
175
|
+
|
|
176
|
+
return frame
|